#include "set_slot_info_action.h"
#include <saas/deploy_manager/scripts/common/scripts_helper.h>
#include <saas/deploy_manager/meta/cluster.h>
#include <saas/library/searchmap/searchmap.h>

namespace NDaemonController {
    NJson::TJsonValue TSetSlotInfoAction::DoSerializeToJson() const {
        NJson::TJsonValue result;
        if (!!Data)
            result.InsertValue("data", Data);
        else {
            result.InsertValue("searchmap", Searchmap);
            result.InsertValue("slot", Slot);
            result.InsertValue("service", Service);
            result.InsertValue("service_type", ServiceType);
            result.InsertValue("ctype", CType);
        }
        return result;
    }

    void TSetSlotInfoAction::DoDeserializeFromJson(const NJson::TJsonValue& json) {
        CHECK_WITH_LOG(json.IsMap());
        NJson::TJsonValue::TMapType::const_iterator i = json.GetMap().find("data");
        if (i != json.GetMap().end())
            Data = i->second.GetStringRobust();
        else {
            Searchmap = json["searchmap"].GetStringRobust();
            Slot = json["slot"].GetStringRobust();
            Service = json["service"].GetStringRobust();
            ServiceType = json["service_type"].GetStringRobust();
            CType = json["ctype"].GetStringRobust();
        }
    }

    void TSetSlotInfoAction::DoInterpretResult(const TString& result) {
        if (!result)
            Fail("Incorrect empty reply for set slot info request");
        else
            Success(result);
    }

    void TSetSlotInfoAction::FailOnAddPrev(const TString& s) {
        TimeStart = Now();
        Status = asInProgress;
        Fail(s);
    }

    void TSetSlotInfoAction::AddPrevActionsResult(const NRTYScript::ITasksInfo& info) {
        TAction::AddPrevActionsResult(info);
        if (!!Data)
            return;
        NJson::TJsonValue searchmap;
        if (info.GetValueByPath(Searchmap, searchmap)) {
            NSaas::TCluster cluster;
            VERIFY_WITH_LOG(cluster.Deserialize(searchmap.GetStringRobust()), "Incorrect cluster representation");

            auto service = cluster.ServiceSearchMap(Service);
            if (!service) {
                FailOnAddPrev("cannot find service " + Service);
                return;
            }

            NSearchMapParser::TSearchMapHost smh;
            if (!service->GetHostBySlot(Slot, smh)) {
                FailOnAddPrev("cannot find slot " + Slot);
                return;
            }

            NSaas::TSlotInfo slotInfo;
            slotInfo.ServiceType = ServiceType;
            slotInfo.DisableIndexing = smh.DisableIndexing;
            slotInfo.DisableSearch = smh.DisableSearch;
            slotInfo.DisableSearchFiltration = smh.DisableSearchFiltration;
            slotInfo.DisableFetch = smh.DisableFetch;
            slotInfo.Slot = Slot;
            slotInfo.ShardMin = smh.Shards.GetMin();
            slotInfo.ShardMax = smh.Shards.GetMax();
            slotInfo.ConfigType = "default";
            slotInfo.Service = Service;
            slotInfo.CType = CType;
            if (NSlotNameUtil::IsNormalDC(smh.DC)) {
                slotInfo.DC = smh.DC;
            } else {
                slotInfo.DC = TDatacenterUtil::Instance().GetDatacenter(smh.Name);
            }

            Data = slotInfo.ToString();
        } else {
            DEBUG_LOG << "Incorrect path " + Searchmap << Endl;
        }
    }

    TSetSlotInfoAction::TFactory::TRegistrator<TSetSlotInfoAction> TSetSlotInfoAction::Registrator(SET_SLOT_INFO_ACTION_NAME);
}
