#pragma once
#include <saas/rtyserver/indexer_core/abstract_model.h>
#include <saas/rtyserver/components/erf/erf_builder.h>
#include <saas/rtyserver/key_inv_processor/ki_maker.h>
#include <saas/rtyserver/components/erf/erf_writer.h>
#include <util/generic/vector.h>
#include "qs_parsed_entity.h"
#include "qs_pos_builder.h"

class TQSMaker {
private:
    TString Name;
    TRTYKIMaker::TPtr Maker;
    TRTYErfDiskManagerPtr Erf;
    TErfWriter::TPtr ErfWriter;
public:
    typedef TAtomicSharedPtr<TQSMaker> TPtr;
    TQSMaker(ui32 actorsCount, const TPathName& dir, const IRTYStaticFactors* factors, const TString& name)
        : Name(name)
    {
        Maker = new TRTYKIMaker(actorsCount, dir.PathName(), "index." + Name + ".", 1 << 10);
        TRTYErfDiskManager::TCreationContext cc(dir, "index." + Name + ".erf", factors);
        cc.BlockCount = 1024;
        Erf = new TRTYErfDiskManager(cc, QS_COMPONENT_NAME);
        ErfWriter = new TErfWriter(Erf.Get());
    }

    void Make(ui32 threadId, const TDocumentQSInfo& doc, ui32 docId) {
        const TDocumentQSInfo::TFactorsByKey& keysFactors = doc.GetData();
        for (TDocumentQSInfo::TFactorsByKey::const_iterator i = keysFactors.begin(), e = keysFactors.end(); i != e; ++i) {
            ui32 position = ErfWriter->Write(i->second);
            SUPERLONG info[2];
            TQSPosBuilder::BuildHits(info[0], info[1], docId, position);
            if (info[1] < info[0]) {
                SUPERLONG t = info[1];
                info[1] = info[0];
                info[0] = t;
            }

            Maker->StorePositions(threadId, i->first.data(), &info[0], 2);
        }
        Maker->IncDoc(threadId);
    }

    void Stop() {
        Maker->Stop();
        Erf->Close();
    }

    void Start() {
        Maker->Start();
        Erf->Open();
    }

    void Close(const NRTYServer::TBuilderCloseContext& context) {
        VERIFY_WITH_LOG(context.SrcDir == context.DstDir, "Not supported");
        Maker->Close(context.RemapTable);
        Erf->Close();
    }

    void Discard() {
        Maker->Discard();
        Erf->Close();
    }
};

class TQSBuilder: public NRTYServer::IIndexComponentBuilder {
private:
    typedef THashMap<TString, TQSMaker::TPtr> TMakers;
    TMakers Makers;
    const NRTYServer::TIndexerConfig& Config;
    TPathName Dir;
public:
    TQSBuilder(const TPathName& dir, const NRTYServer::TIndexerConfig& config, const TString& componentName)
        : NRTYServer::IIndexComponentBuilder(componentName)
        , Config(config)
        , Dir(dir)
    {

    }
    NRTYServer::IIndexComponentManager* GetManager() override { return nullptr; }
    void Index(int threadID, const TParsedDocument& document, const ui32 docId) override;
    bool DoClose(const NRTYServer::TBuilderCloseContext& context) override;
    void DoDiscard() override;
    bool Start() override;
    bool Stop() override;
    void InitInteractions(const NRTYServer::IIndexBuildersStorage& /*storage*/) override {}
};
