#include "action.h"

#include <saas/deploy_manager/meta/cluster.h>
#include <saas/library/searchmap/parsers/json/json.h>
#include <library/cpp/json/writer/json_value.h>
#include <library/cpp/json/json_reader.h>
#include <library/cpp/logger/global/global.h>
#include <util/stream/str.h>

namespace NDaemonController {
    NJson::TJsonValue TSimpleSearchmapModifAction::DoSerializeToJson() const {
        NJson::TJsonValue result;
        result.InsertValue("slots", Slots);
        result.InsertValue("ctype", CType);
        result.InsertValue("action", Action);
        result.InsertValue("service", Service);
        result.InsertValue("service_type", ServiceType);
        result.InsertValue("deploy", Deploy);
        result.InsertValue("deploy_proxies", DeployProxies);
        result.InsertValue("service_info", ServiceInfo);
        result.InsertValue("may_be_dead_interval_percentage", (double)MayBeDeadIntervalPercentage);
        for (const auto& i : RepalceIntervalsMap)
            result["replace_intervals_map"][i.first] = i.second;
        if (!!ResultSearchmap)
            result.InsertValue("result_searchmap", ResultSearchmap);
        return result;
    }

    void TSimpleSearchmapModifAction::DoDeserializeFromJson(const NJson::TJsonValue& json) {
        CHECK_WITH_LOG(json.IsMap());
        Slots = json["slots"].GetStringRobust();
        NSearchMapParser::TSlotsPool pool;
        if (!!Slots && !Slots.StartsWith('$') && !pool.DeserializeFromString(Slots))
            Fail("Incorrect slots data " + Slots);
        CType = json["ctype"].GetStringRobust();
        Service = json["service"].GetStringRobust();
        ServiceType = json["service_type"].GetStringRobust();
        Action = json["action"].GetStringRobust();
        Deploy = json["deploy"].GetBooleanRobust();
        DeployProxies = json["deploy_proxies"].GetBooleanRobust();
        MayBeDeadIntervalPercentage = (float)json["may_be_dead_interval_percentage"].GetDouble();
        ServiceInfo = json["service_info"].GetStringRobust();
        ResultSearchmap = json.Has("result_searchmap") ? json["result_searchmap"].GetStringRobust() : TString();
        for (const auto& j : json["replace_intervals_map"].GetMap())
            RepalceIntervalsMap[j.first] = j.second.GetStringRobust();
    }

    void TSimpleSearchmapModifAction::DoInterpretResult(const TString& result) {
        if (!Deploy) {
            try {
                NSaas::TCluster cluster;
                cluster.Deserialize(result);
                TString error;
                if (!cluster.Validate(error))
                    ythrow yexception() << "incorrect meta: " << error;
                ResultSearchmap = result;
                Success("");
            }
            catch (const yexception& e) {
                Fail("incorrect searchmap: " + result);
            }
        } else
            TClusterAsyncAction::DoInterpretResult(result);
    }

    TSimpleSearchmapModifAction::TSimpleSearchmapModifAction(const NSearchMapParser::TServiceSpecificOptions& serviceInfo, const TString& ctype, const TString& service, const TString& serviceType, bool deploy /*= false*/) : CType(ctype)
        , Service(service)
        , Action("edit_service")
        , ServiceType(serviceType)
        , Deploy(deploy)
    {
        NJson::TJsonValue info;
        NSearchMapParser::TJsonSearchMapParser::SerializeCommonService(info, serviceInfo);
        ServiceInfo = info.GetStringRobust();
    }

    TSimpleSearchmapModifAction::TSimpleSearchmapModifAction(const TString& serviceInfo, const TString& ctype, const TString& service, const TString& serviceType, bool deploy /*= false*/) : CType(ctype)
        , Service(service)
        , Action("edit_service")
        , ServiceType(serviceType)
        , ServiceInfo(serviceInfo)
        , Deploy(deploy)
    {}


    TSimpleSearchmapModifAction::TFactory::TRegistrator<TSimpleSearchmapModifAction> TSimpleSearchmapModifAction::Registrator(MODIF_SEARCHMAP_ACTION_NAME);
}
