#include "solomon_stats_slices_config.h"

#include "beacon.h"

#include <library/cpp/iterator/cartesian_product.h>
#include <library/cpp/iterator/concatenate.h>

template<class T>
THashMap<T, size_t> MakeIndex(const TVector<T> vec) {
    THashMap<T, size_t> result;

    for (auto it = vec.cbegin(); it != vec.cend(); ++it) {
        Y_ASSERT(!result.contains(*it));
        result[*it] = it - vec.cbegin();
    }
    return result;
}

TSolomonStatsSlicesConfig::TSolomonStatsSlicesConfig()
    : Slices(MakeSlices())
    , IdxBySlice(MakeIndex(Slices))
{
}

TVector<TString> TSolomonStatsSlicesConfig::MakeHostSubslices() {
    TVector<TString> result;

    for (const auto& [host, hostSubslicesConfig] : WatchedHosts) {
        result.emplace_back(hostSubslicesConfig.DefaultSlice);
        for (const auto& [sliceName, ipSet] : hostSubslicesConfig.Slices) {
            result.emplace_back(sliceName);
        }
    }
    return result;
}

TVector<TSolomonStatsSlice> TSolomonStatsSlicesConfig::MakeSlices() {
    TVector<TSolomonStatsSlice> result;

    for (const auto& [hostSubslice, status, asn] : CartesianProduct(
        MakeHostSubslices(), TBeacon::AllLegacyStatuses(),
            Concatenate(WatchedASNs, TVector<TString>({DefaultASN})))) {

        result.push_back({hostSubslice, status, asn});
    }
    return result;
}

const THashSet<TString> TSolomonStatsSlicesConfig::WatchedSchemes({"https"});

const THashMap<TString, TSolomonStatsSlicesConfig::THostSubslicesConfig> TSolomonStatsSlicesConfig::WatchedHosts({
    {"yandex.ru", {{
        {"yandex.ru_v4_vla_prio", {
            "5.255.255.5",
            "5.255.255.50",
            "5.255.255.55",
            "5.255.255.60",
            "5.255.255.70",
            "5.255.255.77",
            "5.255.255.80",
            "5.255.255.88",
        }},
        {"yandex.ru_v6", {
            "2a02:6b8:a::a",
        }},
        {"yandex.ru_v4_sas_prio", {
            "77.88.55.50",
            "77.88.55.55",
            "77.88.55.60",
            "77.88.55.66",
            "77.88.55.70",
            "77.88.55.77",
            "77.88.55.80",
            "77.88.55.88",
        }},
    }, "yandex.ru_other"},
}});

const THashSet<TString> TSolomonStatsSlicesConfig::WatchedASNs({
    "AS12389",
    "AS8359",
    "AS16345",
    "AS8402",
    "AS25513",
    "AS12958",
    "AS3216",
    "AS25159",
    "AS31133",
    "AS6697",
    "AS9198",
    "AS29497",
    "AS42610",
    "AS31213",
    "AS12714",
    "AS31163",
    "AS28840",
    "AS1299",
    "AS8369",
    "AS28812",
    "AS24955",
    "AS31205",
    "AS48190",
    "AS41330",
    "AS15774",
    "AS44546",
    "AS48092",
    "AS41733",
    "AS31224",
    "AS20485",
    "AS8997",
});

const TString TSolomonStatsSlicesConfig::DefaultASN = "other";
