#include "installations.h"

#include <library/cpp/uri/uri.h>

#include <util/generic/yexception.h>
#include <util/string/cast.h>
#include <util/string/strip.h>

namespace {
    std::pair<NSaasLB::ELogbrokerName, TString> LogbrokerNameEndpoint[] = {
            std::make_pair(NSaasLB::ELogbrokerName::logbroker, "logbroker.yandex.net"),
            std::make_pair(NSaasLB::ELogbrokerName::logbroker_prestable, "logbroker-prestable.yandex.net"),
            std::make_pair(NSaasLB::ELogbrokerName::lbkx, "lbkx.logbroker.yandex.net"),
            std::make_pair(NSaasLB::ELogbrokerName::lbkxt, "lbkxt.logbroker.yandex.net"),
            std::make_pair(NSaasLB::ELogbrokerName::lbk_saas, "saas.logbroker.yandex.net"),
    };
}

namespace NSaasLB {
    TString FormatLogbrokerName(ELogbrokerName logbroker) {
        TString name = ToString(logbroker);
        std::replace(name.begin(), name.vend(), '_', '-');
        return name;
    }

    TString GetLogbrokerEndpoint(ELogbrokerName logbroker) {
        for (const auto& [name, endpoint] : LogbrokerNameEndpoint) {
            if (name == logbroker) {
                return endpoint;
            }
        }
        ythrow yexception() << "unknown logbroker name: " << logbroker;
    }

    TString GetLogbrokerEndpointWithPort(const TString& endpoint) {
        return endpoint + ":2135";
    }

    TString GetCMLogbrokerEndpointWithPort(const TString& endpoint) {
        return "cm." + endpoint + ":1111";
    }

    TString GetLogbrokerEndpointWithPort(ELogbrokerName logbroker) {
        return GetLogbrokerEndpointWithPort(GetLogbrokerEndpoint(logbroker));
    }

    TString GetCMLogbrokerEndpointWithPort(ELogbrokerName logbroker) {
        return GetCMLogbrokerEndpointWithPort(GetLogbrokerEndpoint(logbroker));
    }

    ELogbrokerName GetLogbrokerNameByEndpoint(const TString& endpoint) {
        for (const auto& [currentName, currentEndpoint] : LogbrokerNameEndpoint) {
            if (currentEndpoint == endpoint) {
                return currentName;
            }
        }
        ythrow yexception() << "unknown logbroker endpoint " << endpoint;
    }

    ELogbrokerName GetLogbrokerNameByEndpointWithPort(const TString& endpoint) {
        NUri::TUri uri;
        auto parsed = uri.Parse(endpoint, NUri::TFeature::FeatureNoRelPath);
        if (NUri::TUri::TState::ParsedOK != parsed) {
            ythrow yexception() << "Unable to parse endpoint " << endpoint << ", error = " << parsed;
        }

        TString host = uri.GetHost().Data();
        return GetLogbrokerNameByEndpoint(host);
    }

    TString GetYtDeliveryPath(ELogbrokerName logbroker) {
        TString pathPrefix = "//home/saas-lb-delivery/";
        if (logbroker == ELogbrokerName::lbk_saas) {
            return pathPrefix + "saas";
        }
        return pathPrefix + FormatLogbrokerName(logbroker);
    }
}
