#include "sys_env.h"
#include "get_value.h"

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

namespace NRTYServer {

void TBallocOptions::InitByDirectives(const TYandexConfig::Directives& directives) {
    GET_VALUE(SoftLimit);
    GET_VALUE(HardLimit);
    GET_VALUE(AllocationThreshold);
    GET_VALUE(SoftReclaimDivisor);
    GET_VALUE(AngryReclaimDivisor);
}

TString TBallocOptions::ToString() const {
    TString s;
    TStringOutput so(s);
    so << "<Balloc>" << Endl;
    so << "SoftLimit : " << SoftLimit << Endl;
    so << "HardLimit : " << HardLimit << Endl;
    so << "AllocationThreshold : " << AllocationThreshold << Endl;
    so << "SoftReclaimDivisor : " << SoftReclaimDivisor << Endl;
    so << "AngryReclaimDivisor : " << AngryReclaimDivisor << Endl;
    so << "</Balloc>" << Endl;
    return s;
}

TSysEnv::TSysEnv() {
    Io["BatchWrite"] = TThrottle::TOptions::FromMaxPerSecond(30_MB, TDuration::Seconds(1));
}

void TSysEnv::Init(const TYandexConfig::TSectionsMap& sysEnvSections) {
    TYandexConfig::TSectionsMap::const_iterator sysEnvIter = sysEnvSections.find("IO");
    if (sysEnvIter != sysEnvSections.end()) {
        const TYandexConfig::TSectionsMap& ioSections = sysEnvIter->second->GetAllChildren();
        for(auto& it : ioSections) {
            InitOneIoOption(it.first, it.second->GetDirectives());
        }
    }
    sysEnvIter = sysEnvSections.find("Balloc");
    if (sysEnvIter != sysEnvSections.end()) {
        BallocOptions.InitByDirectives(sysEnvIter->second->GetDirectives());
    }
}


void TSysEnv::InitOneIoOption(const TString& name, const TYandexConfig::Directives& directives) {
    ui64 BytesPerSecond = 0;
    ui64 SamplingIntervalUS = 0;
    GET_VALUE(BytesPerSecond);
    GET_VALUE(SamplingIntervalUS);
    if (BytesPerSecond && SamplingIntervalUS) {
        Io[name] = TThrottle::TOptions::FromMaxPerSecond(BytesPerSecond, TDuration::MicroSeconds(SamplingIntervalUS));
    }
}

TString TSysEnv::ToString() const {
    TString s;
    TStringOutput so(s);

    so << "<SystemEnvironment>" << Endl;
    so << "<IO>" << Endl;
    for (auto& it : Io) {
        so << "<" << it.first << ">" << Endl;
        so << "BytesPerSecond : " << it.second.GetUnitsPerSecond() << Endl;
        so << "SamplingIntervalUS : " << it.second.SamplingInterval.MicroSeconds() << Endl;
        so << "</" << it.first << ">" << Endl;
    }
    so << "</IO>" << Endl;

    so << BallocOptions.ToString();

    so << "</SystemEnvironment>" << Endl;
    return s;
}

}
