#include "request_wizard.h"
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/logger/global/global.h>

namespace {
    void InitLog() {
        if (!GlobalLogInitialized())
            DoInitGlobalLog("console", 7, false, false);
    }
}

Y_UNIT_TEST_SUITE(TRequestWizardTest) {
    Y_UNIT_TEST(ConvertQuery) {
        InitLog();
        TServerRequestData request;
        request.Parse("/api/projects");

        TRequestWizard::TRequestWizardConfig requestWizardConfig;
        requestWizardConfig.InitFromString("Rules {Method:GET Uri:\"/api/projects\" ResultLua:\"/projects?action=list\"}");

        TRequestWizard requestWizard(requestWizardConfig);
        requestWizard.Process(request, "GET / HTTP/1.1");

        UNIT_ASSERT(TString(request.ScriptName()) == "/projects");
        UNIT_ASSERT(request.CgiParam.Get("action") == "list");
    };

    Y_UNIT_TEST(ConvertQueryWithParams) {
        InitLog();
        TServerRequestData request;
        request.Parse("/api/projects/project");

        TRequestWizard::TRequestWizardConfig requestWizardConfig;
        requestWizardConfig.InitFromString("Rules {Method:GET Uri:\"/api/projects/:project\" ResultLua:\"/projects?action=get&name=${project}\"}");

        TRequestWizard requestWizard(requestWizardConfig);
        requestWizard.Process(request, "GET / HTTP/1.1");

        UNIT_ASSERT(TString(request.ScriptName()) == "/projects");
        UNIT_ASSERT(request.CgiParam.Get("action") == "get");
        UNIT_ASSERT(request.CgiParam.Get("name") == "project");
    };

    Y_UNIT_TEST(ConvertQueryWithTwoRules) {
        InitLog();
        TServerRequestData request;
        request.Parse("/api/projects");

        TRequestWizard::TRequestWizardConfig requestWizardConfig;
        requestWizardConfig.InitFromString("Rules {Method:GET Uri:\"/api/projects\" ResultLua:\"/projects?action=list\"}\n");
        requestWizardConfig.InitFromString("Rules {Method:GET Uri:\"/api/projects/:project\" ResultLua:\"/projects?action=get&name=${project}\"}");

        TRequestWizard requestWizard(requestWizardConfig);
        requestWizard.Process(request, "GET / HTTP/1.1");

        UNIT_ASSERT(TString(request.ScriptName()) == "/projects");
        UNIT_ASSERT(request.CgiParam.Get("action") == "list");
    };

    Y_UNIT_TEST(ConvertQueryWithCgiParams) {
        InitLog();
        TServerRequestData request;
        request.Parse("/api/configs/set_current_version/project?ctype=c&version=v");
        request.CgiParam.Scan(request.Query());

        TRequestWizard::TRequestWizardConfig requestWizardConfig;
        requestWizardConfig.InitFromString(
            "Rules {Method:GET Uri:\"/api/configs/set_current_version/:project\" Cgi:\"ctype\" Cgi:\"version=\" ResultLua:\"/configs?action=set_current_config_version&project=${project}&ctype=${ctype}&version=${version}\"}"
        );

        TRequestWizard requestWizard(requestWizardConfig);
        requestWizard.Process(request, "GET / HTTP/1.1");

        UNIT_ASSERT(TString(request.ScriptName()) == "/configs");
        UNIT_ASSERT(request.CgiParam.Get("project") == "project");
        UNIT_ASSERT(request.CgiParam.Get("action") == "set_current_config_version");
        UNIT_ASSERT(request.CgiParam.Get("ctype") == "c");
        UNIT_ASSERT(request.CgiParam.Get("version") == "v");
    };

    Y_UNIT_TEST(ConvertQueryWithMistakeCgiParams) {
        InitLog();

        TRequestWizard::TRequestWizardConfig requestWizardConfig;
        requestWizardConfig.InitFromString(
            "Rules {Method:GET Uri:\"/api/configs/set_current_version/:project\" Cgi:\"ctype\" Cgi:\"version=\" ResultLua:\"/configs?action=set_current_config_version&project=${project}&ctype=${ctype}&version=${version}\"}"
        );

        TRequestWizard requestWizard(requestWizardConfig);

        TServerRequestData request;
        request.Parse("/api/configs/set_current_version/project?ctype=c");
        request.CgiParam.Scan(request.Query());
        try {
            requestWizard.Process(request, "GET / HTTP/1.1");
        } catch (...) {
            UNIT_ASSERT(false);
            return;
        }

        UNIT_ASSERT(true);

        request.Parse("/api/configs/set_current_version/project?version=v");
        request.CgiParam.Scan(request.Query());

        try {
            requestWizard.Process(request, "GET / HTTP/1.1");
        } catch (...) {
            UNIT_ASSERT(true);
            return;
        }
        UNIT_ASSERT(false);
    };

}
