#include "factors_erf.h"

#include <library/cpp/string_utils/base64/base64.h>
#include <util/string/builder.h>
#include <util/string/cast.h>


void NSaas::AddSimpleStream(const TString& name, const TString& value, NRTYServer::TMessage::TStreamData& streamInfo, bool encode) {
    //TODO(yrum, 20190612): encode==false is never used, and not supported in rty_ann
    streamInfo.SetName(name);
    NRTYServer::TMessage::TStreamData::TValue* streamValue = streamInfo.MutableValue();
    if (value.StartsWith("add:")) {
        if (encode)
            streamValue->SetValue(Base64Encode(TString(value.data() + 4, value.size() - 4)));
        else
            streamValue->SetValue(TString(value.data() + 4, value.size() - 4));
        streamValue->SetAction(NRTYServer::TMessage::TStreamData::ADD);
        //TODO(yrum, 20190612): this does nothing - TStreamData::Action value is not handled in rty_ann
    } else {
        if (encode)
            streamValue->SetValue(Base64Encode(value));
        else
            streamValue->SetValue(value);
    }
}

namespace {
    template<class T>
    void AddSimpleFactorValueImpl(const TString& value, NRTYServer::TMessage::TFactorValues& factorInfo) {
        NRTYServer::TMessage::TFactorValues::TValue* factorValue = factorInfo.AddValues();
        T val;
        if (value.StartsWith("add:")) {
            val = FromString<T>(value.data() + 4);
            factorValue->SetAction(NRTYServer::TMessage::TFactorValues::ADD);
            //TODO(yrum, 20190612): this does nothing - TStreamData::Action value is not handled in rty_ann
        }
        else {
            val = FromString<T>(value);
        }
        float floatVal;
        memcpy(&floatVal, &val, sizeof(floatVal));
        factorValue->SetValue(floatVal);
    }

    template<class T>
    void AddSimpleFactorImpl(const TString& name, const TString& value, NRTYServer::TMessage::TErfInfo& factorInfo) {
        factorInfo.AddNames(name);
        AddSimpleFactorValueImpl<T>(value, *factorInfo.MutableValues());
    }
}

void NSaas::AddSimpleFactor(const TString& name, const TString& value, NRTYServer::TMessage::TErfInfo& factorInfo) {
    AddSimpleFactorImpl<float>(name, value, factorInfo);
}

void NSaas::AddSimpleIntFactor(const TString& name, const TString& value, NRTYServer::TMessage::TErfInfo& factorInfo) {
    AddSimpleFactorImpl<i32>(name, value, factorInfo);
}

void NSaas::AddSimpleFactorValue(const TString& value, NRTYServer::TMessage::TFactorValues& factorInfo) {
    AddSimpleFactorValueImpl<float>(value, factorInfo);
}

void NSaas::AddSimpleIntFactorValue(const TString& value, NRTYServer::TMessage::TFactorValues& factorInfo) {
    AddSimpleFactorValueImpl<i32>(value, factorInfo);
}

void NSaas::ClearFactors(NRTYServer::TMessage::TErfInfo& factorInfo) {
    factorInfo.ClearNames();
    factorInfo.ClearValues();
}

ui64 NSaas::FactorsSize(const NRTYServer::TMessage::TErfInfo& factorInfo) {
    return factorInfo.NamesSize();
}

bool NSaas::IsValidFactorInfo(const NRTYServer::TMessage::TErfInfo& factorInfo) {
    return factorInfo.NamesSize() == factorInfo.GetValues().ValuesSize();
}

TString NSaas::ValueToString(const NRTYServer::TMessage::TFactorValues::TValue& value) {
    TStringBuilder result;
    if (value.HasAction() && value.GetAction() == NRTYServer::TMessage::TFactorValues::ADD) {
        result << "add:";
    }
    result << value.GetValue();
    return result;
}
