#include "deploy_experiments.h"

#include <saas/deploy_manager/server/client/client.h>
#include <saas/deploy_manager/config/config.h>
#include <saas/deploy_manager/scripts/deploy/task.h>

#include <library/cpp/xml/document/xml-document.h>

#include <library/cpp/string_utils/url/url.h>
#include <util/string/type.h>

NRTYDeploy::IScript::TFactory::TRegistrator<NRTYDeploy::TDeployExperimentsScript> NRTYDeploy::TDeployExperimentsScript::Registrator("deploy_experiments");

bool NRTYDeploy::TDeployExperimentsScript::Process(IDeployInfoRequest& request) {
    const bool deploy = IsTrue(request.GetRD().CgiParam.Get("deploy"));

    const TString& configUrl = request.GetConfig().GetExperimentsConfig().ConfigUrl;
    const TString& configPath = request.GetConfig().GetExperimentsConfig().ConfigPath;

    const TStringBuf host = GetHost(CutSchemePrefix(configUrl));
    const TStringBuf handle = GetPathAndQuery(CutSchemePrefix(configUrl));

    TNetworkAddress address(TString(host), 80);
    TSocket local(address, TDuration::Seconds(10));
    TSocketOutput so(local);
    TSocketInput si(local);
    so << "GET " << handle << " HTTP/1.1\r\n"
          "Host: " << host << "\r\n\r\n";
    so.Flush();
    THttpInput input(&si);

    ui64 code = ParseHttpRetCode(input.FirstLine());
    TString xml = input.ReadAll();
    if (code != 200) {
        request.Output() << "HTTP/1.1 500 \r\n\r\n";
        request.Output() << configUrl << " is unavailable" << Endl;
        return true;
    }

    NXml::TDocument doc(xml, NXml::TDocument::String);
    const TString& version = doc.Root().Attr<TString>("version");

    request.GetStorage().SetValue(configPath, xml);
    if (deploy) {
        TClusterTask::TCgiContext context = TClusterTask::TCgiContext::Parse(request.GetRD().CgiParam);
        context.Service = SEARCH_PROXY_SERVICE;
        context.ServiceType = SEARCH_PROXY_SERVICE;
        NRTYDeploy::TDeployTask task(context, "NEW", &request, 0.1, nullptr, "", false);
        task.BuildTask();
        if (task.GetCurrentStatus() == TClusterTask::ctsEnqueued) {
            request.Output() << "HTTP/1.1 200 \r\n\r\n";
            request.Output() << task.GetId() << Endl;
        } else if (task.GetResultStatus() == TClusterTask::rsDuplication) {
            request.Output() << "HTTP/1.1 400 \r\n\r\n";
            request.Output() << "duplication" << Endl;
        } else {
            request.Output() << "HTTP/1.1 500 \r\n\r\n";
            request.Output() << "Fail code: " << RSToString(task.GetResultStatus()) << ". Message: " << task.GetStatusInfo();
        }
    } else {
        request.Output() << "HTTP/1.1 200 \r\n\r\n";
        request.Output() << version << Endl;
    }

    return true;
}
