#include "reducer.h"
#include "common.h"
#include <google/protobuf/messagext.h>
#include <kernel/multipart_archive/multipart.h>
#include <util/folder/dirut.h>

namespace {
    TString GetBaseLayer(TFsPath segmentDir, TString defVl) {
        // "auto-select" mode for UrlsOnly
        TString prefix;
        for (const TString prefix : { "indexfullarc.base", "indexfullarc.full" }) {
            if (TArchiveOwner::Exists(segmentDir / prefix))
                return prefix;
        }
        return defVl;
    }
}

void TFullarcReducer::Do(NYT::TTableReader<NYT::Message>* input, NYT::TTableWriter<NYT::TNode>* output) {
    auto compression = Params.GetCompression().empty() ? "COMPRESSED" : Params.GetCompression();
    auto shardDispatcher = CreateShardDispatcher(Params);
    NRTYArchive::TMultipartConfig layerConfig;
    layerConfig.Compression = FromString<NRTYArchive::IArchivePart::TType>(compression);
    {
        TYTChunkedInputToFiles fileReader(input, TFsPath("./"));
        fileReader.ProcessAll();
    }
    TDirsList fl;
    fl.Fill("./");

    bool urlsOnly = false;
    THolder<IFormatDumper> dumper;
    TString dumpFormat = Params.GetDumpFormat().empty() ? "Message" : Params.GetDumpFormat();
    if (dumpFormat == "Message") {
        dumper = MakeHolder<TMessageDumper>(output, shardDispatcher.Get());
    } else if (dumpFormat == "UrlsOnly") {
        dumper = MakeHolder<TDirDumper>(output, shardDispatcher.Get());
        urlsOnly = true;
    } else {
        dumper = MakeHolder<TDebugDumper>(output, shardDispatcher.Get());
    }
    for (TFsPath segmentDir(fl.Next()); !!segmentDir; segmentDir = fl.Next()) {
        INFO_LOG << segmentDir << Endl;
        TString prefix;
        if (urlsOnly)
            prefix = GetBaseLayer(segmentDir, GetLayerPrefix(Params));
        else
            prefix = GetLayerPrefix(Params);

        TArchiveOwner::TPtr archive = TArchiveOwner::Create(segmentDir / prefix, layerConfig, 0, true);

        NRTYArchive::TMultipartArchive::TIteratorPtr archiveIterator = archive->CreateIterator();
        ReadArchive(*archiveIterator, dumper.Get());
        RemoveDirWithContents(segmentDir);
    }
}
REGISTER_REDUCER(TFullarcReducer);
