#pragma once

#include "wrap-vector.hpp"
#include "wrap-string.hpp"
#include "wrap-sstream.hpp"

#include <ostream>
#include <memory>

class DebugCollector : public eng::nevernew {
private:
    // At any given time, the stringstream may contain one
    // extra line that hasn't yet been appended to the list of lines.
    // The flag 'need_flush_' is true if the stringstream contains
    // an extra line.  In that case, is_regular_ indicates whether
    // the extra line is a header or a regular line.
    eng::vector<eng::string> lines_;
    eng::vector<eng::string> targets_;
    int n_regular_;
    bool need_flush_;
    bool is_regular_;
    bool active_;
    void flush();
    bool use(const char *target);
public:
    eng::ostringstream oss_;
    DebugCollector();
    DebugCollector(const eng::string &targets);
    bool do_header();
    bool do_line();
    void dump(std::ostream &os);
    friend class DebugBlock;
};

class DebugBlock : public eng::nevernew {
private:
    DebugCollector *dbc_;
    int n_regular_;
    size_t n_lines_;
    bool active_;
public:
    DebugBlock(DebugCollector *dbc, const char *target);
    ~DebugBlock();
};

#define DebugHeader(dbc) if (((dbc)!=nullptr) && (dbc)->do_header()) ((dbc)->oss_)
#define DebugLine(dbc) if (((dbc)!=nullptr) && (dbc)->do_line()) ((dbc)->oss_)


