#pragma once

#include <saas/library/daemon_base/module/module.h>
#include <saas/rtyserver/config/config.h>
#include <saas/protos/rtyservice.pb.h>
#include <saas/library/sharding/sharding.h>
#include <google/protobuf/messagext.h>
#include <google/protobuf/text_format.h>

#include <util/generic/set.h>
#include <util/stream/file.h>
#include <util/system/fs.h>

class TSuggestZonesInfo {
private:
    TMap<TString, NRTYService::TSuggestZoneInfo> Zones;
    ui64 DefaultWeight;
public:
    bool IsUsefulZone(const TString& zoneName) const {
        return Zones.contains(zoneName);
    }
    ui64 GetWeight(const TString& zoneName) const {
        CHECK_WITH_LOG(IsUsefulZone(zoneName));
        return Zones.find(zoneName)->second.GetWeight();
    }

    ui64 GetDefaultWeight() const {
        return DefaultWeight;
    }

    void Deserialize(const TString& fileName) {
        VERIFY_WITH_LOG(NFs::Exists(fileName), "Incorrect path %s", fileName.data());
        TUnbufferedFileInput fi(fileName);
        NRTYService::TSuggestZonesInfo zones;
        CHECK_WITH_LOG(google::protobuf::TextFormat::ParseFromString(fi.ReadAll(), &zones));
        DefaultWeight = zones.GetDefaultWeight();
        for (ui32 i = 0; i < zones.ZonesSize(); ++i) {
            NOTICE_LOG << "Suggest zone: " << zones.GetZones(i).GetZoneName() << "/" << zones.GetZones(i).GetWeight() << Endl;
            Zones[zones.GetZones(i).GetZoneName()] = zones.GetZones(i);
        }
    }
};

class TSuggestComponentConfig: public TPluginConfig<TRTYServerConfig::IComponentConfig> {
private:
    TSuggestZonesInfo ZonesInfo;
    TInterval<NSearchMapParser::TShardIndex> Shards;
    bool ClearUnusefulData;
    ui32 WordsCountToSave;
    ui32 WordsCountToReject;
    bool IndexPrefixes;
    ui32 MaxDocumentsPortion;
    TVector<TString> FilterDictionaries;
    bool SaveOriginalText;
    TString AllowedSpecSimbols;
    ui32 MaxWordLength;
    bool UseEncodingFromPage;
    ui32 DefaultPruneCount;
    TSet<TString> AttributesBlacklist; // format: "i_skip_suggest:1;i_ignore_suggest:1"

protected:
    virtual bool DoCheck() const;
    virtual void DoInit(const TYandexConfig::Section& componentSection);
    virtual void DoToString(IOutputStream& so) const;
public:
    TSuggestComponentConfig()
    {
        IndexPrefixes = false;
        WordsCountToSave = 6;
        WordsCountToReject = 12;
        MaxDocumentsPortion = 1 << 20;
        AllowedSpecSimbols = "0123456789 -";
        SaveOriginalText = false;
        MaxWordLength = 0;
        UseEncodingFromPage = false;
        DefaultPruneCount = Max<ui32>();
    }

    ui32 GetDefaultPruneCount() const {
        return DefaultPruneCount;
    }

    ui32 GetMaxWordLength() const {
        return MaxWordLength;
    }

    ui32 GetWordsCountToSave() const {
        return WordsCountToSave;
    }

    ui32 GetMaxDocumentsPortion() const {
        return MaxDocumentsPortion;
    }

    ui32 GetWordsCountToReject() const {
        return WordsCountToReject;
    }

    bool GetClearUnusefulData() const {
        return ClearUnusefulData;
    }

    bool GetSaveOriginalText() const {
        return SaveOriginalText;
    }

    bool GetUseEncodingFromPage() const {
        return UseEncodingFromPage;
    }

    const TString& GetAllowedSpecSimbols() const {
        return AllowedSpecSimbols;
    }

    const TSuggestZonesInfo& GetSuggestZonesInfo() const;
    const TInterval<NSearchMapParser::TShardIndex>& GetShards() const {
        return Shards;
    }

    const TVector<TString>& GetFilterDictionaries() const {
        return FilterDictionaries;
    }

    const TSet<TString>& GetAttributesBlacklist() const {
        return AttributesBlacklist;
    }

    TString ZonesWeightsFileInfo;
};
