#include "dump.h"

#include <library/cpp/getopt/last_getopt.h>
#include <util/string/split.h>

using namespace NLastGetopt;
using namespace NRtDoc;

int main(int argc, const char** argv) {
    DoInitGlobalLog("cerr", TLOG_DEBUG, false, false);

    TOpts opts = TOpts::Default();
    opts.AddHelpOption();
    opts.SetFreeArgsNum(1);
    opts.SetFreeArgTitle(0, "FILE", "prep file (prep.lumps or portions.xxx)");
    bool optBlobRow = false;
    bool optBlobCell = false;
    bool optNoOffroad = false;
    bool useHex = false;
    opts.AddCharOption('b', "Dump rows as blobs").StoreTrue(&optBlobRow);
    opts.AddCharOption('c', "Dump cells as blobs").StoreTrue(&optBlobCell);
    opts.AddCharOption('D', "Disable Offroad parsers (only print protobufs)").StoreTrue(&optNoOffroad);
    opts.AddCharOption('o', "Print only particular tables (prepids, comma separated)").OptionalArgument("PREP").Optional();
    opts.AddCharOption('i', "Print one row (final docid)").OptionalArgument("DOC").Optional();
    opts.AddCharOption('h', "Use hex format for blobs").StoreTrue(&useHex);

    TOptsParseResult args(&opts, argc, argv);

    EDumpLevel dumpLevel = EDumpLevel::ProtobufTable;
    if (optBlobRow) {
        dumpLevel = (EDumpLevel)Min<i32>(dumpLevel, EDumpLevel::Blob);
    }
    if (optBlobCell) {
        dumpLevel = (EDumpLevel)Min<i32>(dumpLevel, EDumpLevel::Row);
    }
    if (dumpLevel >= EDumpLevel::ProtobufTable && !optNoOffroad) {
        dumpLevel = EDumpLevel::Max;
    }

    TSet<TString> filterPrepIds;
    if (args.Has('o')) {
        const TString value = args.Get<TString>('o');
        StringSplitter(value).Split(',').AddTo(&filterPrepIds);
    }
    TMaybe<ui32> oneDocId;
    if (args.Has('i')) {
        oneDocId = args.Get<ui32>('i');
    }

    try {
        TFsPath file = args.GetFreeArgs().at(0);
        file.CheckExists();

        TPrepTable tbl(file);
        tbl.Init();

        TRtDocDumper dumper;
        dumper.SetPrepIds(filterPrepIds);
        dumper.SetLevel(dumpLevel);
        dumper.Start(Cout);
        dumper.SetUseHex(useHex);
        for (IPrepIterator::TPtr item = tbl.Open(); item->Next();) {
            if (oneDocId.Defined() && item->GetData().FinalDocId != oneDocId.GetRef()) {
                continue;
            }

            dumper.Dump(*item);
        }
        dumper.Finish();

    } catch (...) {
        ERROR_LOG << CurrentExceptionMessage() << Endl;
    }
};
