#pragma once

#include "serviceconfig.h"

#include <saas/library/daemon_base/config/daemon_config.h>
#include <saas/library/daemon_base/module/module.h>
#include <saas/library/searchmap/searchmap.h>
#include <saas/searchproxy/logging/loggerconfig.h>
#include <saas/rtyserver/factors/factors_config.h>
#include <saas/library/flow/mirror.h>

#include <library/cpp/http/server/options.h>
#include <library/cpp/yconf/conf.h>

#include <util/datetime/base.h>
#include <util/generic/map.h>
#include <util/generic/ptr.h>
#include <util/generic/string.h>

class TSearchProxyConfig: TSectionParser<TAnyYandexConfig>, public IServerConfig {
public:
    typedef TMap<TString, TServiceConfig> TServicesConfigs;
    typedef TVector<TString> TSchemes;

    struct TAppHostConfig {
        struct TTvmParams {
            bool Enabled = false;
            ui64 TvmId = 0;
            TVector<ui64> AllowedSourceTvmIds;
        };

        struct TGrpcParams {
            bool Enabled = false;
            ui16 Port = 0;
            ui32 Threads = 0;
        };

        bool Enabled = false;
        ui16 Port = 0;
        TGrpcParams Grpc;
        TTvmParams Tvm;
    };

    struct TTvmParams {
        bool Enabled = false;
        bool EnableUserTickets = false;
        ui32 TvmId = 0;
        ui32 FlowMirrorTvmId = 0;
        TString DiskCacheDir;
        ui32 TvmProxyTvmId = 0;
        TVector<ui32> AllowedUserAbcGroups;
        ui32 AbcApiTvmId = 0;
    };

private:
    const TDaemonConfig DaemonConfig;
    ui32 HttpServerInstances;
    THttpServerOptions HttpServerOptions;
    THttpServerOptions NehServerOptions;
    TSchemes NehServerSchemes;
    NSearchMapParser::TSearchMap SearchMap;
    bool UpperSearch;
    TCopyPtr<TLoggerConfig> LoggerConfig;
    TString WorkDir;
    TString AuthKeyWord;
    TServiceConfig DefaultServiceConfig;
    TServicesConfigs ServicesConfigs;
    TFlowMirror::TConfig FlowMirrorConfig;
    TAppHostConfig AppHostConfig;
    TDuration SleepBeforeListen;
    TTvmParams Tvm;
    TServiceDiscoveryOptions ServiceDiscoveryOptions;

private:
    void ParseMode();
    void ParseAppHostConfig();
    void ParseAppHostTvmConfig(const TYandexConfig::Section& section, TAppHostConfig::TTvmParams& tvm);
    void ParseAppHostGrpcConfig(const TYandexConfig::Section& section, TAppHostConfig::TGrpcParams& grpc);
    void ParseTvmConfig();
    void ParseConfig(TConfigPatcher& preprocessor);
    void ParseLogger();
    void ParseServices(TConfigPatcher& preprocessor);
    void ParseSearchMap(TConfigPatcher& preprocessor);
    void ParseFlowMirrorConfig();

public:
    TSearchProxyConfig(const TServerConfigConstructorParams& params);

    TSearchProxyConfig(const char* config, const TDaemonConfig& daemonConfig,
        const NSearchMapParser::TSearchMap& searchMap, TConfigPatcher& preprocessor);

    const TServiceConfig& GetServiceConfig(const TString& service) const;
    const TServicesConfigs& GetServicesConfigs() const;

    virtual TSet<TString> GetModulesSet() const override {
        return {};
    }

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

    inline ui32 GetHttpServerInstances() const {
        return HttpServerInstances;
    }

    inline const THttpServerOptions& GetHttpServerOptions() const {
        return HttpServerOptions;
    }

    inline const THttpServerOptions& GetNehServerOptions() const {
        return NehServerOptions;
    }

    inline const TSchemes& GetNehServerSchemes() const {
        return NehServerSchemes;
    }

    inline const NSearchMapParser::TSearchMap& GetSearchMap() const {
        return SearchMap;
    }

    inline const TString& GetAuthKeyWord() const {
        return AuthKeyWord;
    }

    inline const TFlowMirror::TConfig& GetFlowMirrorConfig() const {
        return FlowMirrorConfig;
    }

    inline const TCopyPtr<TLoggerConfig>& GetLoggerConfig() const {
        return LoggerConfig;
    }

    inline const TAppHostConfig& GetAppHostConfig() const {
        return AppHostConfig;
    }

    inline const TDuration GetSleepBeforeListen() const {
        return SleepBeforeListen;
    }

    inline const TTvmParams& GetTvmParams() const {
        return Tvm;
    }

    inline const TServiceDiscoveryOptions& GetServiceDiscoveryOptions() const {
        return ServiceDiscoveryOptions;
    }
};

