#pragma once

#include "fwd.h"
#include "text_machine_config.h"
#include "zone_extractor_config.h"

#include <saas/library/daemon_base/module/module.h>
#include <saas/rtyserver/model/realm/realm.h>
#include <saas/rtyserver/synchronizer/library/config/config.h>
#include <saas/services/abstract/rty_indexation.h>
#include <saas/util/types/shard_index.h>

#include <search/cache_options/cache_options.h>

#include <kernel/qtree/request/reqattrlist.h>
#include <kernel/tarc/enums/searcharc.h>
#include <kernel/groupattrs/config.h>
#include <kernel/multipart_archive/config/config.h>

#include <library/cpp/streams/special/throttle.h>
#include <library/cpp/langs/langs.h>

#include <util/generic/size_literals.h>

class TConfigPatcher;
class TPruningConfig;

namespace NOxygen {
    class TOxygenOptions;
}

namespace NRTYFactors {
    class TConfig;
}

class TSearchConfig;

THolder<NOxygen::TOxygenOptions> GetOxygenOptions(const TString& file, TConfigPreprocessor* preprocessor);

struct TRTYServerConfig: public IServerConfig {
public:
    enum TRTYCachePolicy {
        cpNoCache               /* "NOCACHE" */,
        cpCacheLifeTime         /* "CACHE_WITH_LIVE_TIME" */,
        cpCacheLifeTimeModified /* "CACHE_WITH_LIVE_TIME_MODIFICABLE" */,
        cpUnknown               /* "UNKNOWN" */
    };
private:
    mutable TRTYCachePolicy CachePolicy;

public:
    THolder<NRTYServer::TSysEnv> SysEnv;
    THolder<NRTYServer::TSearcherConfig> SearcherConfig;
    THolder<NRTYServer::TSearchServerOptions> BaseSearcherConfig;
    THolder<NRTYServer::TSearchServerOptions> MetaSearcherConfig;
    THolder<NRTYServer::TRepairConfig> RepairConfig;

    const NRTYServer::TSysEnv& GetSysEnv() const;
    NRTYServer::TSysEnv& GetSysEnv();
    const NRTYServer::TSearcherConfig& GetSearcherConfig() const;
    NRTYServer::TSearcherConfig& GetSearcherConfig();
    const NRTYServer::TSearchServerOptions& GetBaseSearcherConfig() const;
    NRTYServer::TSearchServerOptions& GetBaseSearcherConfig();
    const NRTYServer::TSearchServerOptions& GetMetaSearcherConfig() const;
    NRTYServer::TSearchServerOptions& GetMetaSearcherConfig();
    const NRTYServer::TRepairConfig& GetRepairConfig() const;
    NRTYServer::TRepairConfig& GetRepairConfig();

    NRTYServer::TResourceFetchConfig GlobalResourceFetchConfig;

    class IComponentConfig: public IAbstractModuleConfig {
    public:
        typedef NObjectFactory::TObjectFactory<IComponentConfig, TString> TFactory;
    };

    class IExternalLogicConfig: public IAbstractModuleConfig {
    public:
        typedef NObjectFactory::TObjectFactory<IExternalLogicConfig, TString> TFactory;
    };

    class IKVStorageConfig: public IAbstractModuleConfig {
    public:
        typedef NObjectFactory::TObjectFactory<IKVStorageConfig, TString> TFactory;
    };

    enum TVerificationPolicy {
        vpRelease /* "Release" */,
        vpTesting /* "Testing" */,
        vpIndexingUniqueUrls /* "IndexingUniqueUrls" */
    };

    THolder<NRTYServer::TMergerConfig> MergerConfig;
    THolder<NRTYServer::TLoggerConfig> LoggerConfig;
    THolder<NRTYServer::TMonitorConfig> MonitorConfig;
    THolder<NRTYServer::TCommonIndexersConfig> CommonIndexers;

    const NRTYServer::TMergerConfig& GetMergerConfig() const;
    NRTYServer::TMergerConfig& GetMergerConfig();
    const NRTYServer::TLoggerConfig& GetLoggerConfig() const;
    NRTYServer::TLoggerConfig& GetLoggerConfig();
    const NRTYServer::TMonitorConfig& GetMonitorConfig() const;
    NRTYServer::TMonitorConfig& GetMonitorConfig();
    const NRTYServer::TCommonIndexersConfig& GetCommonIndexers() const;
    NRTYServer::TCommonIndexersConfig& GetCommonIndexers();

    TPluginConfigs<IComponentConfig> ComponentsConfig;
    TPluginConfigs<IExternalLogicConfig> ExternalLogicConfig;
    TPluginConfigs<IDaemonModuleConfig> ModulesConfig;
    TPluginConfigs<IKVStorageConfig> StoragesConfig;

    TString IndexDir;
    TString IndexGenerator;
    IExternalServiceLogic::TPtr ExternalServiceLogic;
    ui32 DeadDocsClearIntervalSeconds = 20;
    ui32 DeadIndexesClearIntervalSeconds = 20;
    bool IsPrefixedIndex;
    bool AddSignalTags;
    TString DDKManager;
    TString UrlToDocIdManager;
    NSearchMapParser::TShardIndex ShardMin = 0;
    NSearchMapParser::TShardIndex ShardMax = 0;

    TVerificationPolicy VerificationPolicy;
    bool IsSecondaryMetaServiceComponent;
    bool DoStoreArchive;
    bool UseExtendedProcessors;
    THolder<NRTYServer::TShardsConfig> Shards;
    bool IsReadOnly;
    bool NoMorphology;
    TString MorphologyLanguages;
    TString PreferedMorphologyLanguages;
    ui32 SearchersCountLimit = 0;
    TVector<TString> WatchdogOptionsFiles;

    TString Components;
    TSet<TString> ComponentsSet;
    TString AdditionalModules;
    TVector<TString> AdditionalModulesVector;
    bool PreserveModulesOrder = false;
    THolder<NRTYServer::TIndexerConfigMemory> IndexerMemoryConfig;
    THolder<NRTYServer::TIndexerConfigDisk> IndexerDiskConfig;
    THolder<NRTYServer::TRealmListConfig> RealmListConfig;
    THolder<TPruningConfig> Pruning;

    const NRTYServer::TIndexerConfigMemory& GetIndexerMemoryConfig() const;
    NRTYServer::TIndexerConfigMemory& GetIndexerMemoryConfig();
    const NRTYServer::TIndexerConfigDisk& GetIndexerDiskConfig() const;
    NRTYServer::TIndexerConfigDisk& GetIndexerDiskConfig();
    const NRTYServer::TRealmListConfig& GetRealmListConfig() const;
    NRTYServer::TRealmListConfig& GetRealmListConfig();
    const NRTYServer::TShardsConfig& GetShardsConfig() const;
    NRTYServer::TShardsConfig& GetShardsConfig();

    TConfigPatcher* ConfigPatcher;
    const TDaemonConfigPtr DaemonConfigHolder;
    const TDaemonConfig& DaemonConfig;
    THashMap<TString, TString> FileDigests;
    THashMap<TString, i32> ConfigsVersions;

    // Probaly need to hardcode "true" and remove this option. See r4706922 and SAASSUP-528 for more details.
    bool CanIgnoreIndexOriginOnRemoving = true;

    virtual const IAbstractModuleConfig* GetModuleConfigImpl(const TStringBuf name) const override {
        return ModulesConfig.Get<IAbstractModuleConfig>(name);
    }

    const TDaemonConfig& GetDaemonConfig() const override {
        return DaemonConfig;
    }

    TRTYServerConfig(const TServerConfigConstructorParams& params);
    TRTYServerConfig(TDaemonConfigPtr daemonConfig);
    ~TRTYServerConfig();

    void InitFromString(const TString& configText);
    void Init(const TYandexConfig::Directives& directives);
    TSet<TString> GetModulesSet() const override;
    TVector<TString> GetModulesVector() const override;
    TString ToString() const;

    bool RealtimeEnabled() const;

    bool GetIsPrefixedIndex() const {
        return IsPrefixedIndex;
    }

    bool GetAddSignalTags() const {
        return AddSignalTags;
    }

    TRTYCachePolicy GetCachePolicy() const;

    void ParseConfigsVersion();
};

THolder<TRTYServerConfig> ParseRtyConfig(const TString& configText, const THashMap<TString, TString>& variables);
