#include "deploy_int_builder.h"
#include "dc_alias_filter.h"

#include <saas/library/searchmap/searchmap.h>
#include <saas/library/searchmap/parsers/json/json.h>
#include <saas/deploy_manager/scripts/common/file_content_generators/searchmap.h>
#include <saas/deploy_manager/scripts/common/file_content_generators/environment.h>
#include <saas/deploy_manager/scripts/common/file_content_generators/description.h>
#include <saas/deploy_manager/scripts/common/global_names/global_names.h>
#include <library/cpp/json/json_reader.h>

namespace NRTYDeployInfo {

    TINTDeployServiceInfo::TFactory::TRegistrator<TINTDeployServiceInfo> TINTDeployServiceInfo::Registrator(INT_SERVICE);
    TINTDeployComponentInfo::TFactory::TRegistrator<TINTDeployComponentInfo> TINTDeployComponentInfo::Registrator(INT_SERVICE);

    bool TINTDeployServiceInfo::DoBuildFilesInfo(const NRTYDeploy::TFileContentGenerator::TContext& context, TStringStream& errors, bool forcedOnly) {
        if (!TRealServiceDeployInfo::DoBuildFilesInfo(context, errors, forcedOnly))
            return false;
        Nodes.push_back(new NRTYDeploy::TSearchMapContentGenerator(*GetCommon(), GetCType(), INT_SERVICE));

        NSaas::TSlotInfo slotInfo;
        slotInfo.CType = GetCType();
        slotInfo.ServiceType = INT_SERVICE;
        slotInfo.Service = context.SlotInfo.Service;

        NRTYDeploy::TFileContentGenerator::AddGenerators(Nodes, *GetCommon(), "configs/" + context.SlotInfo.Service, "intsearch-", slotInfo);
        return true;
    }

    NSearchMapParser::TSearchMapService* TINTDeployServiceInfo::ServiceSearchMap(NSaas::TCluster& cluster) {
        return cluster.IntMetaServiceMutable(Service);
    }

    NSearchMapParser::TSearchMapService* TINTDeployServiceInfo::AddService(NSaas::TCluster& cluster, const TString& name) {
        return cluster.AddIntService(name);
    }

    bool TINTDeployServiceInfo::RemoveService(NSaas::TCluster& cluster) {
        return cluster.RemoveIntService(Service);
    }

    bool TINTDeployServiceInfo::DisableNotFirstReplics() const {
        return false;
    }

    TString TINTDeployServiceInfo::GetConfigsPath() const {
        return "/configs/" + ComponentInfo->GetComponentName();
    }

    NSearchMapParser::TSearchMap TINTDeployComponentInfo::DoSearchMap(const TString& service) const {
        const NSearchMapParser::TSearchMap& resultTemp = SearchMap();

        if (service == GetComponentName())
            return resultTemp;
        else {
            NSearchMapParser::TSearchMap result;
            const NSearchMapParser::TSearchMapService* servInfo = resultTemp.GetService(service);
            if (servInfo) {
                result.AddService(service) = *servInfo;
            }
            return result;
        }
    }

    const NSearchMapParser::TSearchMap& TINTDeployComponentInfo::SearchMap() const {
        const NSaas::TClusterConst* clusterPtr = NSaas::TClusterLocker::DefineConst(*GetCommon(), GetCType());
        if (!clusterPtr) {
            ythrow yexception() << "Incorrect cluster info for " << GetCType();
        }
        return clusterPtr->IntMetaSearchMap();
    }

    TString TINTDeployComponentInfo::GetSearchMapBySlotKey(const TString& slotName, const TString& /*dc*/) const {
        return slotName;
    }

    NSearchMapParser::TSearchMap TINTDeployComponentInfo::DoSearchMapBySlot(const TString& slotName, const NSaas::TClusterConst* clusterPtr, const TString& dc) const {
        NRTYCluster::TSlotData slotData;
        if (!NRTYCluster::TSlotData::Parse(slotName, slotData)) {
            ythrow yexception() << "incorrect slot name: " << slotName;
        }

        TString alias = slotData.GetDCAlias(true, dc);
        return NRTYDeploy::TDCAliasFilter(alias).Process(clusterPtr->IntMetaSearchMap(slotName));
    }

    TString TINTDeployComponentInfo::GetComponentName() const {
        return INT_SERVICE;
    }

}
