#pragma once

#include "ranking_pass.h"

#include <saas/rtyserver/factors/user_factors_calcer.h>

#include <kernel/externalrelev/relev.h>
#include <search/base/inforequestdata.h>

class TRTYIndexData;
class TRTYTextIndexData;
class TZoneGator;
class TSaasTextMachineFeaturesCalcer;
class TWeighedDoc;
class TFactorsCalcer;
class IRTYCgiReader;
class TFactorsMaskCache;
class TRTYMakeupManager;

class TRTYRelevance : public IRelevance {
public:
    TRTYRelevance(const TFactorsMaskCache& factorsMaskCache, const TRTYIndexData* indexData, const IRTYCgiReader& rtyCgi, const TBaseIndexData& baseIndexData, const TRequestParams* rp);
    ~TRTYRelevance();

    virtual bool ShouldRemoveDocument(TCalcFactorsContext& ctx, TSumRelevParams& srParams) override;
    virtual bool ShouldRemoveDocument(const TWeighedDoc& doc) override;

    virtual void PreInitRequest(TRequestParams* rp) override;

    virtual void CreateGators(TCreateGatorsContext& /*ctx*/) const override;
    virtual IInfoRequestPrinter* CreateInfoRequestPrinter(const TString& type) override;

    const IFactorsInfo* GetFactorsInfo() const override;
    virtual const char* GetFormulaName() override;
    virtual void CalcFactors(TCalcFactorsContext& ctx) override;
    virtual void CalcRelevance(TCalcRelevanceContext& ctx) override;
    virtual void FillProperties(TSearcherProps *props) const override;
    virtual bool ExtractSnippetsHits(ui32 docId, const TSnippetsHitsContext* shc) override;
    virtual void FillPerQueryParams(TFillPerQueryParamsContext& ctx) const override;
    virtual TVector<const char*> SerializeAttributes(const TWeighedDoc& doc, TArrayRef<const char * const> attrNames, IAttributeWriter& write, const TRequestResults* results) const override;
    virtual TVector<const char*> SerializeFirstStageAttributes(const TWeighedDoc& doc, TArrayRef<const char * const> attrName, IAttributeWriter& write, const TRequestResults* results) const override;

    virtual void OnBeforeSecondPass() override;
    virtual bool UseWebDocQuorum() const override;
    virtual bool UsesVirtualFactorDomain() const override;

    virtual bool GetSwitchType(ESwitchType& switchType) const override;

    virtual IDocTimeCalcer* CreateDocTimeCalcer() override;

    ICreatorOfCustomDynamicFeaturesCalcer* CreateCustomDynamicFeaturesCalcerCreator() override;

    virtual TTextMachineFeaturesCalcer* CreateExternalTextMachineCalcer(const bool needOpenIterators) override;
    virtual const TMap<ui32, NTextMachineProtocol::TPbHits>* GetTextMachineDocHits() const override;
    virtual const TMap<ui32, NTextMachineProtocol::TPbLimitsMonitor>* GetTextMachineDocLimitsMonitors() const override;
    virtual const THashMap<ui32, NTextMachineProtocol::TPbQueryWordStats>* GetTextMachineDocWordStats() const override;
    bool ShouldDoublePruningTargetDocs() const override;
private:
    TFactorsCalcer* GetMainCalcer() const;
    TFactorsCalcer* GetFastCalcer() const;
    TFactorsCalcer* GetCurrentCalcer() const;

    void SerializeErfAttributes(ui32 docId, TArrayRef<const TStringBuf> names, IAttributeWriter& write) const;
    void SerializePropAttributes(ui32 docId, TArrayRef<const TStringBuf> names, IAttributeWriter& write) const;
    void SerializeUserDefinedAttributes(ui32 docId, TArrayRef<const TStringBuf> names, IAttributeWriter& write) const;
    void SerializeFirstStageProperties(ui32 docId, TArrayRef<const TStringBuf> names, IAttributeWriter& write) const;
    void SerializeFirstStageFactors(const TWeighedDoc& doc, TArrayRef<const TStringBuf> names, IAttributeWriter& write) const;
    class TDocTimeCalcer;

    void OnBeforePass() const;
    void OnBeforeFirstPass() const;

    TSaasTextMachineCalcerHolder DoCreateExternalTextMachineCalcer(const bool needOpenIterators);

    void FillRtyFactorsProperty(TSearcherProps* props) const;

private:
    const TFactorsMaskCache& FactorsMaskCache;
    const IRTYCgiReader* Cgi = nullptr;
    const TRTYMakeupManager* Makeup = nullptr;
    const NRTYFactors::TConfig* Factors = nullptr;
    const IDDKManager* DDKManager;
    mutable TZoneGator* ZoneGator = nullptr;
    const TRTYIndexData* IndexData = nullptr;
    const TBaseIndexData& BaseIndexData;
    mutable THolder<TFactorsCalcer> MainFactorsCalcer;
    mutable THolder<TFactorsCalcer> FastFactorsCalcer;
    TRTYRankingOpts RankingOpts;
    NRTYFactors::TUserDefinedAttrsStorage UserDefinedAttrs;

    TMemoryPool MemPool;
    TRTYRankingPassContext RankingPass;
    const TRequestParams& RP;
};
