#include "block_merger.h"
#include <library/cpp/logger/global/global.h>
#include <util/thread/pool.h>

namespace NRTYMerger {

    bool TBlockMerger::Merge(TContext& context) {
        try {
            TVector<IHeader::TPtr> headers(Sources.size(), nullptr);
            for (ui32 source = 0; source < Sources.size(); ++source) {
                headers[source] = Sources[source]->ReadHeader();
                for (ui32 i = 0; i < Dests.size(); ++i) {
                    Dests[i]->AddHeader(headers[source].Get());
                }
            }

            for (ui32 i = 0; i < Dests.size(); ++i) {
                TRTYMerger::TAddress addr;
                Y_VERIFY(Dests[i]->WriteHeader(Decoder.GetNewDocsCount(i)), "Incorrect operation");
                ui32 docsWrite = 0;
                for (ui32 idDoc = 0; Decoder.NewToOld(i, idDoc, addr); ++idDoc) {
                    IObject::TPtr object = Sources[addr.ClusterId]->ReadObject(addr.DocId);
                    if (!Dests[i]->WriteObject(headers[addr.ClusterId], object))
                        return false;
                    if (context.StopFlag && *context.StopFlag)
                        return false;
                    ++docsWrite;
                }
                Y_VERIFY(Decoder.GetNewDocsCount(i) == docsWrite, "Inconsistent documents count");
                if (!Dests[i]->Finish()) {
                    return false;
                }
            }
        }
        catch (...) {
            ERROR_LOG << "Block merger failed: " << CurrentExceptionMessage() << Endl;
            return false;
        }
        return true;
    }

}
