#pragma once

#include "search_server_options.h"
#include "text_machine_config.h"

#include <search/cache_options/cache_options.h>

#include <kernel/tarc/enums/searcharc.h>

#include <library/cpp/yconf/conf.h>

#include <util/generic/string.h>
#include <util/generic/vector.h>

class TDuration;
class TSearchConfig;
class TReqAttrList;
struct TRTYServerConfig;

namespace NRTYFactors {
    class TConfig;
}

namespace NRTYServer {

    struct TSearcherConfig {
    public:
        enum TFiltrationModelType {
            fmWeight /* "WEIGHT" */,
            fmSimple /* "SIMPLE" */,
            fmWeb    /* "WEB" */
        };
        enum TSearchConfigType {
            sctBase = 0,
            sctMemory,
            sctMeta,
            sctCount
        };
    public:
        bool AutoStartServer;
        bool ExceptionOnSearch = false;
        bool DelegateRequestOptimization;
        bool Enabled;
        TString AccessLog;
        bool EnableUrlHash;
        bool BroadcastFetch;
        bool SkipSameDocids;
        bool LockIndexFiles;
        bool LockUrl2DocId;
        bool TwoStepQuery;
        bool RetryStartMetasearch = false;
        bool RedirectSearchErrorLogToGlobal = true;
        TString LocalHostName;
        TVector<TString> SearchPath;
        TString Limits;
        TString RequestLimits;
        TString ReportMethod;
        TString ReportModule;
        TRTYServerConfig& Owner;
        TString WildcardSearch;
        bool UseRTYExtensions;
        TString ExternalSearch;
        TString CustomBaseSearch;
        TString ReArrangeOptions;
        THolder<TReqAttrList> ReqAttrList;
        TString QueryLanguage;
        TCacheOptions CacheOptions;
        TCacheOptions FastCacheOptions;
        TString EventLog;
        bool AsyncSearch;
        TString LoadLogMeta;
        TString LoadLogBase;
        TString PassageLogMeta;
        TString PassageLogBase;
        TString ArchivePolicy;
        EArchiveType ArchiveType;
        ui32 TiersCount;
        ui32 TierMinSize;
        ui32 TiersOverlapPercent;
        bool RawPassages;
        TString FactorsInfo;
        bool KeepAllDocuments;
        TString SnippetsDeniedZones;
        TVector<TString> SnippetsDeniedZonesVector;
        TFiltrationModelType FiltrationModel;
        TAtomicSharedPtr<NRTYFactors::TConfig> Factors;
        TString FactorsModels;
        TTextMachineConfig TextMachine;
        bool ReAskBaseSearches;
        size_t ArchiveCacheSizeMb;
        ui32 PageScanSize;
        TString LocalSearcherHost;
        ui64 PrefetchSizeBytes;
        TSearchServerOptions ServerOptions{"SrchHttpListen", "SrchHttpReq", "SrchHttpFailReq"};
        TString DefaultBaseSearchConfig;
        TString DefaultMemorySearchConfig;
        TString DefaultMetaSearchConfig;
        TString AdditionalLockedFiles;
        TString AdditionalPrefetchedFiles;
        TString WarmupQueries;
        TVector<TAtomicSharedPtr<TSearchConfig> > DefaultConfigInstances;
        ui32 GroupPruningCoefficient;
        TString CustomSearcher = "default";
        bool AllowEmptyNehReplier;
        bool EnableCacheForDbgRlv = false;
        bool AskFactorsOnSearchStage = false;
        TString ProtocolType = "proto";
        double MergeMultiplier = 0.0;

    public:
        TSearcherConfig(TRTYServerConfig& owner);
        ~TSearcherConfig();
        void Init(TYandexConfig& yandexConfig, const TYandexConfig::Section* section, TConfigPreprocessor *configPreprocessor);
        void Init(const TYandexConfig::Directives& directives, TConfigPreprocessor *configPreprocessor);
        void InitCacheOptions(TCacheOptions& cacheOptions, const TYandexConfig::Directives& directives);
        TString ToString() const;
        TString ToStringCacheOptions(const TCacheOptions& cacheOptions) const;

        TDuration GetScatterTimeout() const {
            return TDuration::MicroSeconds(ScatterTimeout);
        }

        const TString& GetPersistentSearchDir() const;

        bool DelegationIsActive() const;

    private:
        ui64 ScatterTimeout = 60 * 1000 * 1000;
        void AddDefaultConfigInstance(const TString& configPath, TSearchConfigType searcherType, TConfigPreprocessor *configPreprocessor);
    };

}
