#include "thread_opts.h"
#include <saas/library/daemon_base/protos/threading.pb.h>
#include <saas/library/string_utils/kv_proto_opts.h>
#include <util/generic/map.h>
#include <util/stream/str.h>

namespace NThreading {

class TThreadingConfig::TImpl {
public:
    TMap<TString, TPoolOpts> LoadTypeOpts;
};

const TPoolOpts* TThreadingConfig::GetPoolOpts(const TString& loadType) const {
    const auto& map = Impl->LoadTypeOpts;
    auto iter = map.find(loadType);
    return (iter != map.end()) ? &iter->second : nullptr;
}

TThreadingConfig::TThreadingConfig()
    : Impl(MakeHolder<TImpl>())
{
}

TThreadingConfig& TThreadingConfig::operator=(const TThreadingConfig& other) {
    PresetName = other.GetPresetName();
    Impl = MakeHolder<TImpl>(*other.Impl.Get());
    return *this;
}

TThreadingConfig::TThreadingConfig(const TThreadingConfig& other) {
    *this = other;
}

TThreadingConfig::~TThreadingConfig() {
}

TPoolOpts TThreadingConfig::ParsePoolOpts(const TString& strOpts) {
    return NUtil::ParseKvOptions<TPoolOpts>(strOpts);
}

void TThreadingConfig::Init(const TYandexConfig::Directives& directives) {
    directives.GetValue("PresetName", PresetName);

    const auto* descr = NThreading::TLoadtype_descriptor();
    for (auto i = 0; i < descr->value_count(); i++) {
        const auto* loadType = descr->value(i);
        TString key = loadType->name(); //i.e.: Search, Indexer
        TString vl;
        if (directives.GetNonEmptyValue(key, vl)) {
            const TPoolOpts opts = ParsePoolOpts(vl);
            Impl->LoadTypeOpts.insert(std::make_pair(std::move(key), std::move(opts)));
        }
    }
}

void TThreadingConfig::ToString(TStringStream& so) const {
    so << "PresetName : " << PresetName << Endl;
    const auto* descr = NThreading::TLoadtype_descriptor();
    for (auto i = 0; i < descr->value_count(); i++) {
        const auto* loadType = descr->value(i);
        TString key = loadType->name(); //i.e.: Search, Indexer
        const TPoolOpts* vl = GetPoolOpts(loadType->name());
        if (!vl)
            continue;

        TString str = NUtil::FormatKvOptions(*vl);
        so << key << " : " << str << Endl;
    }
}

} // NThreading
