#pragma once

#include <kernel/externalrelev/relev.h>
#include <kernel/tarc/docdescr/docdescr.h>
#include <ysite/yandex/srchmngr/arcdata.h>
#include <search/reqparam/reqparam.h>
#include <search/session/reqenv.h>
#include <saas/rtyserver/search/processors/processor.h>

class IFastArchive;

class TFacetBuilder: public TRTYFacetBase, public IDocInfosBuilderCallback {
public:
    static const ui32 DefaultTop = 1 << 31;
    static const ui32 DefaultMaxCateg = 1000;

public:
    enum FacetMode {
        SINGLE,
        ALL,
        INTERLEAVING
    };
    struct TPropertyFacetHelper: THashMap<TString, ui32> {
        ui32 TimesUsed = 0;
        ui32 Top = DefaultTop;
        ui32 MaxCateg = DefaultMaxCateg;
        bool Fast = false;
    };
private:
    const IArchiveData& AD;
    const IFastArchive* FA;
    THashMap<TString, TPropertyFacetHelper> Result;
    TSet<TString> ForcedProperties;
    TSet<TString> ForcedFastProperties;
    TSet<TString> IgnoredProperties;
    TString PropertyPrefix;
    ui32 ProcessedDocCount;
    FacetMode Mode;
public:
    TFacetBuilder(const IArchiveData& ad, const IFastArchive* fa, FacetMode mode,
                  const TVector<TString>& forcedProperties,
                  const TVector<TString>& forcedFastProperties,
                  const TVector<TString>& ignoredProperties,
                  const TString& propertyPrefix);

    void FillProperties(TSearcherProps* props) const override;
    void OnBuildProperty(const char* name, const char* value) override;
    void ProcessDoc(ui32 docId, const NGroupingAttrs::TDocsAttrs& /*da*/) override;

    static FacetMode DetermineMode(const TString& mode);
    static TString StripFacetOptions(const TString& facet);

private:
    void ProcessArchive(ui32 docId);
    void ProcessFastArchive(ui32 docId);
    void PreprocessProperties(const TVector<TString>& original, TSet<TString>& target);
    bool IgnoreProperty(const TStringBuf& property) const;
};
