#pragma once

#include <saas/rtyserver/indexer_core/abstract_model.h>
#include <saas/rtyserver/config/fwd.h>

class TCSManager;
class TDDKManager;
class TQSManager;
class IDDKManager;
class IRTYErfManager;
class TRTYMakeupManager;
class TRTYFastArchiveManager;
class TRTYIndexTextData;
class TAnnIndexManager;
class IDocLenCalcer;
class ISentenceZonesReader;

namespace NRTYServer {
    class IPropManager;
}

namespace NGroupingAttrs {
    class TDocsAttrs;
}

namespace NIndexAnn {
    class TReaders;
}

namespace NRTYFeatures {
    class TImportedFunctions;
}

class TRTYIndexData: public IIndexData {
public:
    struct TIndexDataDetails;
private:
    const IIndexController::TPtr IndexController;
    const NRTYServer::IRTYIndexManager* RTYIndexManager;
    const IRTYErfManager* RTYErfManager;
    const TRTYMakeupManager* MakeupManager;
    const TRTYFastArchiveManager* FastArchiveManager;
    const TQSManager* QSManager;
    const TCSManager* CSManager;
    const IDDKManager* DDKManager;
    const TAnnIndexManager* AnnIndexManager;
    const NRTYServer::TSearcherConfig* RTYSearcherConfig;
    const NGroupingAttrs::TDocsAttrs* DocsAttrs;
    const IDocLenCalcer* DocLenCalcer;
    const NRTYServer::IPropManager* PropManager;
    const THolder<TIndexDataDetails> IndexDataDetails; // external factorann readers, etc.
    const THolder<TRTYIndexTextData> IndexTextOpts;
    const THolder<NRTYFeatures::TImportedFunctions> ImportedFunctions;

public:
    TRTYIndexData(
        IIndexController::TPtr index,
        const NRTYServer::TSearcherConfig* rtySearcherConfig,
        const IDocLenCalcer* docLenCalcer
    );

    ~TRTYIndexData();

    virtual void Open(const char* /*indexDir*/, bool /*isPolite*/, const TSearchConfig* /*config*/) override {}
    virtual void Close() override {}
    virtual void SetIndexDataOptions(TBaseIndexDataOptions& options) const override;

    TBaseIndexDynamicData* CreateBaseIndexDynamicData(const TSearchConfig& /*config*/, const TBaseIndexDataOptions& /*options*/) override;

    IIndexController::TPtr GetIndexController() const {
        return IndexController;
    }

    const NRTYServer::IRTYIndexManager* GetIndexManager() const {
        return RTYIndexManager;
    }

    const TAnnIndexManager* GetAnnManager() const {
        return AnnIndexManager;
    }

    const TRTYMakeupManager* GetMakeupManager() const {
        return MakeupManager;
    }

    // returns MakeupManager as an interface
    const ISentenceZonesReader* GetMakeupReader() const;

    const TRTYFastArchiveManager* GetFastArchiveManager() const {
        return FastArchiveManager;
    }

    const IDDKManager* GetDDKManager() const {
        return DDKManager;
    }

    const TQSManager* GetQSManager() const {
        return QSManager;
    }

    const TCSManager* GetCSManager() const {
        return CSManager;
    }

    const IRTYErfManager* GetErfManager() const {
        return RTYErfManager;
    }

    const NRTYFactors::TConfig* GetFactorsConfig() const {
        return RTYSearcherConfig->Factors.Get();
    }

    const NRTYServer::TSearcherConfig* GetRTYSearcherConfig() const {
        return RTYSearcherConfig;
    }

    const NGroupingAttrs::TDocsAttrs* GetDocsAttrs() const {
        return DocsAttrs;
    }

    void SetDocsAttrs(const NGroupingAttrs::TDocsAttrs* docsAttrs) {
        DocsAttrs = docsAttrs;
    }

    const IDocLenCalcer* GetDocLenCalcer() const {
        return DocLenCalcer;
    }

    const NRTYServer::IPropManager* GetPropManager() const {
        return PropManager;
    }

    const NIndexAnn::TReaders* GetFactorAnnReaders(const TBaseIndexData& bid) const;

    const TRTYIndexTextData& GetIndexTextOpts() const {
        return *IndexTextOpts;
    }

    NRTYFeatures::TImportedFunctions* GetImportedFunctions() {
        return ImportedFunctions.Get();
    }

    const NRTYFeatures::TImportedFunctions* GetImportedFunctions() const {
        return ImportedFunctions.Get();
    }

private:
    template <class T>
    const T* GetManager(const TString& name) const {
        Y_ASSERT(IndexController);
        return dynamic_cast<const T*>(IndexController->GetManager(name));
    }
};
