#include "script.h"
#include "task.h"

#include <saas/deploy_manager/scripts/cluster/cluster_task.h>
#include <saas/deploy_manager/scripts/common/scripts_helper.h>
#include <saas/deploy_manager/server/client/client.h>
#include <saas/util/cluster/cluster.h>
#include <library/cpp/json/json_writer.h>
#include <library/cpp/logger/global/global.h>
#include <util/charset/utf8.h>
#include <util/charset/wide.h>
#include <util/stream/str.h>


namespace NRTYDeploy {

    template <class T>
    bool ReadCgi(IDeployInfoRequest& request, const TString& cgiName, bool mustbe, T& value) {
        if (mustbe || request.GetRD().CgiParam.Has(cgiName)) {
            if (!TryFromString<T>(request.GetRD().CgiParam.Get(cgiName), value)) {
                request.Output() << "HTTP/1.1 400 \r\n\r\n";
                request.Output() << "Incorrect " << cgiName << " " << request.GetRD().CgiParam.Get(cgiName);
                return false;
            }
        }
        return true;
    }

    TClusterTask::TPtr TScriptAddReplicas::DoBuildTask(IDeployInfoRequest& request) const {
        NRTYCluster::TSlotsAllocator sa;
        const TString& allocatorStr = request.GetRD().CgiParam.Get("slots_allocator");
        if (!sa.DeserializeFromString(allocatorStr)) {
            request.Output() << "HTTP/1.1 400 \r\n\r\n";
            request.Output() << "Incorrect slots allocator description";
            return nullptr;
        }
        bool restore = true;
        if (request.GetRD().CgiParam.Has("restore")) {
            restore = FromString<bool>(request.GetRD().CgiParam.Get("restore"));
        }

        bool allocateOnly = false;
        if (request.GetRD().CgiParam.Has("allocate_only")) {
            allocateOnly = FromString<bool>(request.GetRD().CgiParam.Get("allocate_only"));
        }
        const ui32 replicasCount = FromString(request.GetRD().CgiParam.Get("replicas_count"));
        const TClusterTask::TCgiContext context = TClusterTask::TCgiContext::Parse(request.GetRD().CgiParam);
        ui32 slotsCount = 0;
        if (!ReadCgi(request, "slots_count", true, slotsCount) || !replicasCount) {
            request.Output() << "HTTP/1.1 400 \r\n\r\n";
            request.Output() << "Incorrect data about slots_count/replicas_count";
            return nullptr;
        }
        bool deployProxy = !request.GetRD().CgiParam.Has("deploy_proxy") || FromString<bool>(request.GetRD().CgiParam.Get("deploy_proxy"));

        float mayBeDeadIntervalPercentage = 0.01f;
        if (request.GetRD().CgiParam.Has("may_be_dead_procentage")) {
            mayBeDeadIntervalPercentage = FromString<float>(request.GetRD().CgiParam.Get("may_be_dead_procentage"));
        }


        return new TAddReplicaTask(slotsCount, sa, context, &request, replicasCount, restore, allocateOnly, deployProxy, mayBeDeadIntervalPercentage);
    };

    IScript::TFactory::TRegistrator<TScriptAddReplicas> TScriptAddReplicas::Registrator("add_replica");
}
