#include "deploy_block.h"

namespace NRTYDeploy {

    TDeployBlockMaker::TDeployBlockMaker(const TString& service, const TString& ctype, IDeployInfoRequest& request)
        : Service(service)
        , CType(ctype)
        , Request(request)
    {
        StoragePath = "/configs/" + service + "/deploy_block.conf-" + ctype;
    }

    bool TDeployBlockMaker::GetState(NJson::TJsonValue& conf, bool& isBlocked) const {
        isBlocked = false;
        TString content;
        if (!Request.GetStorage().GetValue(StoragePath, content)) {
            return false;
        }
        TStringInput si(content);
        if (!NJson::ReadJsonTree(&si, &conf)) {
            return false;
        }
        isBlocked = (conf.Has("blocked") && conf["blocked"].GetBooleanRobust());
        return true;
    }

    bool TDeployBlockMaker::IsBlocked() const {
        NJson::TJsonValue blockConf;
        bool isBlocked = false;
        GetState(blockConf, isBlocked);
        return isBlocked;
    }

    bool TDeployBlockMaker::SetBlocked(const NJson::TJsonValue& jsConf) {
        TStringStream ss;
        NJson::WriteJson(&ss, &jsConf, true, true);
        if (!Request.GetStorage().SetValue(StoragePath, ss.Str())) {
            return false;
        }
        return true;
    }

    bool TDeployBlockMaker::Remove() {
        if (Request.GetStorage().ExistsNode(StoragePath)) {
            Request.GetStorage().RemoveNode(StoragePath);
            return true;
        }
        return true;
    }

    bool TScriptDeployBlock::Process(IDeployInfoRequest& request) {
        TString action = request.GetRD().CgiParam.Get("action");
        TString service = request.GetRD().CgiParam.Get("service");
        TString ctype = request.GetRD().CgiParam.Get("ctype");
        if (!ctype  || !service) {
            request.Output() << "HTTP/1.1 400 \r\n\r\n";
            request.Output() << "service or ctype does not set";
            return true;
        }

        TDeployBlockMaker blocker(service, ctype, request);
        NJson::TJsonValue result;
        NJson::TJsonValue blockConf;
        if (action == "get") {
            bool isBlocked = false;
            if (blocker.GetState(blockConf, isBlocked)) {
                result["details"] = blockConf;
            }
            result["blocked"] = isBlocked;
            request.Output() << "HTTP/1.1 200 \r\n\r\n";
            TStringStream ss;
            NJson::WriteJson(&ss, &result, true, true, false);
            request.Output() << ss.Str();
        } else if (action == "set") {
            blockConf["author"] = request.GetRD().CgiParam.Get("author");
            blockConf["reason"] = request.GetRD().CgiParam.Get("reason");
            blockConf["blocked"] = true;
            bool success = blocker.SetBlocked(blockConf);
            request.Output() << "HTTP/1.1 " << (success ? "200" : "400") << " \r\n\r\n";
            request.Output() << (success ? "OK" : "Failed to set");
        }  else if (action == "remove") {
            bool success = blocker.Remove();
            request.Output() << "HTTP/1.1 " << (success ? "200" : "400") << " \r\n\r\n";
            request.Output() << (success ? "OK" : "Failed to remove");
        } else {
            request.Output() << "HTTP/1.1 400 \r\n\r\n";
            request.Output() << "unknown action " << action;
        }
        return true;
    }

    IScript::TFactory::TRegistrator<TScriptDeployBlock> TScriptDeployBlock::Registrator("deploy_block");
}
