#include "ctype_task.h"
#include <saas/deploy_manager/scripts/logic/action.h>
#include <saas/deploy_manager/scripts/common/global_names/global_names.h>

#include <saas/library/daemon_base/controller_actions/execute_script.h>
#include <saas/deploy_manager/scripts/common/deploy/deploy_builder.h>
#include <saas/library/searchmap/searchmap.h>
#include <library/cpp/json/json_reader.h>

#include <saas/deploy_manager/scripts/process_alerts/service_actions/action_update.h>

using namespace NRTYDeploy;

namespace NRTYAlerts {

    TAlertsCTypeTask::TAlertsCTypeTask(const TClusterTask::TCgiContext& context, NRTYDeploy::ICommonData* commonData)
        : TClusterTask(context, commonData, CTYPE_ALERTS_TASK_TYPE)
    {};

    bool TAlertsCTypeTask::ValidateCType(TString& errorMessage) {
        if (!CType) {
            errorMessage = "empty ctype";
            return false;
        }
        const TString prefix = CommonData->GetConfig().GetAlertsConfig().GetCtypesPrefix();
        if (!CType.StartsWith(prefix)) {
            errorMessage = "alerts for ctype " + CType + " disabled";
            return false;
        }
        return true;
    }

    bool TAlertsCTypeTask::BuildServicesActions() {
        const TVector<TString> comps({RTYSERVER_SERVICE, META_SERVICE_SERVICE});
        TVector<TString> services;
        for (const auto& comp : comps) {
            NRTYDeployInfo::IDeployComponentInfo::TPtr info = NRTYDeployInfo::IDeployComponentInfo::TFactory::Construct(comp);
            info->SetInfo(CommonData, CType);
            const NSearchMapParser::TSearchMap* ism;
            ism = &info->SearchMap();
            for (auto& service : ism->GetInternalSearchMap()) {
                services.push_back(service.Name);
            }
            for (auto& metaService : ism->GetMetaServices()) {
                services.push_back(metaService.Name);
            }
        }
        Sort(services);
        TVector<NRTYScript::TTaskContainer> predTasks;
        for (const auto& service : services) {
            predTasks.push_back(GetScript()->AddAction(CommonData->GetDeployManagerBalanserHost(), CommonData->GetDeployManagerBalanserPort(), CommonData->GetDeployManagerBalanserUriPrefix(),
                new TAlertsUpdateAction(service, CType)));
        }
        if (!!predTasks) {
            GetScript()->AddDependentAction<NRTYScript::TSucceededChecker>(CommonData->GetDeployManagerBalanserHost(), CommonData->GetDeployManagerBalanserPort(),
            CommonData->GetDeployManagerBalanserUriPrefix(), new NRTYDeploy::TLogicAction(), predTasks);
        }
        return true;
    }

    void TAlertsCTypeTask::DoBuildTask() {
        try {
            TString errorMessage;
            if (!ValidateCType(errorMessage)) {
                SetStatus(ctsFailed, TClusterTask::rsFailedOnConstruction, errorMessage);
                return;
            }
            BuildServicesActions();
        } catch (...) {
            SetStatus(ctsFailed, TClusterTask::rsFailedOnConstruction, CurrentExceptionMessage());
        }
    }

};
