#pragma once

#include "task.h"
#include <saas/deploy_manager/scripts/cluster/cluster_task.h>
#include <library/cpp/json/writer/json_value.h>

#define DEPLOY_ACTION_NAME "DEPLOY_ACTION"

namespace NRTYDeploy {

    class TDeployAction : public NRTYDeploy::TClusterAsyncAction {
    private:
        TString ServiceType;
        TString Service;
        TString CType;
        TString Version;
        float MayBeDeadInIntervalPercentage;
        THolder<NSearchMapParser::TSlotsPool> SlotsFilter;
        TString ForceServices;
        bool DiffSlotsOnly;

    protected:

        virtual NJson::TJsonValue DoSerializeToJson() const override;
        virtual void DoDeserializeFromJson(const NJson::TJsonValue& json) override;

        static TFactory::TRegistrator<TDeployAction> Registrator;
    public:

        TDeployAction() {}

        TDeployAction(const TString& service, const TString& ctype, TString version,
            NDaemonController::TAsyncPolicy aPolicy, const TString& serviceType, float mayBeDeadInIntervalPercentage = 0.01f,
            const NSearchMapParser::TSlotsPool* slotsFilter = nullptr, const TString& forceServices = TString(),
            bool diffSlotsOnly = false)
            : TClusterAsyncAction(aPolicy)
            , MayBeDeadInIntervalPercentage(mayBeDeadInIntervalPercentage)
            , SlotsFilter(slotsFilter ? new NSearchMapParser::TSlotsPool(*slotsFilter) : nullptr)
            , ForceServices(forceServices)
            , DiffSlotsOnly(diffSlotsOnly)
        {
            ServiceType = serviceType;
            Service = service;
            CType = ctype;
            Version = version;
        }

        virtual ui32 GetAttemptionsMaxResendStart() const override {
            return 1;
        }

        virtual TDuration GetTimeoutDuration() const override {
            return TDuration::Seconds(60);
        }

        virtual TString GetCustomUriStart() const override {
            return "deploy";
        }

        virtual bool GetNotContinuableTaskOnStarting() const override {
            return false;
        }

        virtual TString DoBuildCommandStart() const override {
            return "service=" + Service +
                "&ctype=" + CType +
                "&version=" + Version +
                "&may_be_dead_procentage=" + ToString(MayBeDeadInIntervalPercentage) +
                "&force_services=" + ForceServices +
                "&service_type=" + ServiceType +
                "&diff_slots_only=" + ToString(DiffSlotsOnly) +
                (!!SlotsFilter ? ("&slots=" + SlotsFilter->Serialize().GetStringRobust()) : TString())
                ;
        }

        virtual TString ActionId() const override {
            return NRTYDeploy::TClusterAsyncAction::ActionId() + "/" + Service;
        }

        virtual TString ActionName() const override {
            return DEPLOY_ACTION_NAME;
        }

    };
}
