#pragma once

#include <saas/rtyserver/common/common_rty.h>
#include <saas/rtyserver/config/config.h>
#include <saas/rtyserver/indexer_core/abstract_model.h>
#include <saas/rtyserver/components/generator/manager.h>

#include <kernel/tarc/dirconf/dirconf.h>
#include <kernel/indexer/baseproc/baseconf.h>

class TBaseGeneratorBuilder: public NRTYServer::IDTIndexBuilder {
protected:
    const TRTYServerConfig& RTYConfig;
    TAtomic DocsCount;
    TVector<ui32> FailedDocs;

    ui32 GetTrivialResortMap(const IIndexController::TPtr index, TVector<ui32>& result) const;

public:
    TBaseGeneratorBuilder(const TRTYServerConfig& rtyConfig, const TString& componentName)
        : NRTYServer::IDTIndexBuilder(componentName)
        , RTYConfig(rtyConfig)
    {
        DocsCount = 0;
    }

    virtual bool DoWriteMeta(NRTYServer::TIndexMetadata& metaData) const override {
        metaData.SetIsPrefixed(RTYConfig.IsPrefixedIndex);
        return true;
    }

    NRTYServer::IIndexComponentManager* GetManager() override {
        return nullptr;
    }

    virtual bool CheckIndexDocIds(const TString& indexPath) const = 0;

    // Gets the final map for enumerating docids (not specific to Merge)
    virtual ui32 GetResortMapForMerge(const IIndexController::TPtr index, TVector<ui32>& result) const {
        return GetTrivialResortMap(index, result);
    }

    void InitInteractions(const NRTYServer::IIndexBuildersStorage& /*storage*/) override {
    }

    void Index(int /*threadID*/, const TParsedDocument& /*document*/, const ui32 /*docId*/) override {
        AtomicIncrement(DocsCount);
    }
};

//
// TBaseIndexBuilder: The interface of Server.IndexGenerator
// Responsible for pruning and removal of DocIds
//
class TBaseIndexBuilder: public TBaseGeneratorBuilder {
public:
    TBaseIndexBuilder(const TRTYServerConfig& rtyConfig, const TString& componentName);

    virtual bool CheckIndexDocIds(const TString& indexPath) const;

    // Gets the final map for enumerating docids (not specific to Merge)
    virtual ui32 GetResortMapForMerge(const IIndexController::TPtr index, TVector<ui32>& result) const;

    virtual void Index(int threadID, const TParsedDocument& document, const ui32 docId);
private:
    typedef TMap<double, TVector<ui32> > TResortMap;
    TResortMap ResortMap;
    ITransaction ResortMapLocker;
    THolder<TPruningConfig::ICalcer> PruningCalcer;
};
