#pragma once

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

#include <util/generic/string.h>

namespace NOxygen {
    class TOxygenOptions;
}

namespace NRTYServer {

    struct TCommonIndexersConfig;
    struct TRealmConfig;

    struct TIndexerConfig {
    public:
        ui32 Threads;
        ui32 DocumentsQueueSize;
        ui32 ConnectionTimeout;
        bool PreparatesMode = false; // 'true' means making PREPARED segments
        ui32 MaxDocuments;
        ui32 MaxSegments;
        ui32 TimeToLiveSec = 0;
        ui32 TimeToLiveExtra = 30;
        bool AllowSameUrls = true;
        i32 PhaseToLiveSec = -1;
        ui32 DbgMaxDocumentsTotal = 0;
        const TCommonIndexersConfig& Common;
        TRealmConfig* RealmConfig;
    private:
        TString TypePort; // Cache

    public:
        TIndexerConfig(const TCommonIndexersConfig& common);
        virtual ~TIndexerConfig();

        const TString& GetDirectory() const;

        void Init(const TYandexConfig::Section* section);
        void ToString(TStringOutput& so) const;

        const TString& GetTypeWithPort() const noexcept {
            return TypePort;
        }

        virtual const TString& GetType() const = 0;
        virtual const NOxygen::TOxygenOptions* GetOxygenOptions() const = 0;
        virtual void InitByDirectives(const TYandexConfig::Directives& directives);
        virtual void ToStringDirectives(TStringOutput& so) const;
    };

    struct TIndexerConfigDisk;

    struct TIndexerConfigMemory : public TIndexerConfig {
    public:
        bool Enabled;
        ui64 GarbageCollectionTime;
        ui32 MaxDocumentsReserveCapacityCoeff;
        ui32 DocumentsLimit;
        TString RealTimeLoadC2P;
        TString RealTimeFeatureConfig;
        TString RealTimeExternalFilesPath;
        TString RealTimeOxygenOptionsFile;
        THolder<NOxygen::TOxygenOptions> RealTimeOxygenOptions;

    public:
        TIndexerConfigMemory(const TCommonIndexersConfig& common);

        const TIndexerConfigDisk& PretendAsDisk() const;

        virtual const TString& GetType() const override;
        virtual const NOxygen::TOxygenOptions* GetOxygenOptions() const override;
        virtual void ToStringDirectives(TStringOutput& so) const override;
        virtual void InitByDirectives(const TYandexConfig::Directives& directives) override;

    private:
        THolder<TIndexerConfigDisk> DiskConfig;
    };

    struct TIndexerConfigDisk : public TIndexerConfig {
    public:
        ui32 CloseThreads;
        bool SearchEnabled = false;
        ui32 PortionDocCount;
        bool WaitCloseForMerger;
        TString SearchObjectsDirectory;
        const NOxygen::TOxygenOptions* OxygenOptionsPtr; //an override which may be set for pseudoRT Indexer. See PretendAsDisk

    public:
        TIndexerConfigDisk(const TCommonIndexersConfig& common);

        virtual const TString& GetType() const override;
        virtual const NOxygen::TOxygenOptions* GetOxygenOptions() const override;
        virtual void ToStringDirectives(TStringOutput& so) const override;
        virtual void InitByDirectives(const TYandexConfig::Directives& directives) override;
    };

}
