#include "maps/wikimap/mapspro/services/mrc/libs/db/include/toloka/task_type_info.h"
#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>

#include <library/cpp/testing/common/env.h>
#include <library/cpp/testing/gtest/gtest.h>
#include <maps/libs/common/include/exception.h>

namespace maps::mrc::common::tests {
using namespace ::testing;

TEST(Config_should, render_builtin_templated_configs) {
    vault_boy::MemoryContext ctx{
        {"POSTGRESQL_PASSWORD", "Db-Pass-Test-1"},
        {"POSTGRESQL_PASSWORD_TESTING", "Db-Pass-Test-1"},
        {"MDS_AUTH_HEADER", "Mds-Auth-Header-Test-1"},
        {"MDS_AUTH_HEADER_TESTING", "Mds-Auth-Header-Test-1"},
        {"MDS_PUBLIC_AUTH_HEADER", "Mds-Public-Auth-Header-Test-1"},
        {"MDS_PUBLIC_AUTH_HEADER_TESTING", "Mds-Public-Auth-Header-Test-1"},
        {"TOLOKA_AUTH_HEADER", "Toloka-Auth-Header-Test-1"},
        {"TOLOKA_AUTH_HEADER_TESTING", "Toloka-Auth-Header-Test-1"},
        {"YANG_AUTH_HEADER_TESTING", "Yang-Auth-Header-Test"},
        {"YANG_AUTH_HEADER", "Yang-Auth-Header-Test"},
        {"YT_HAHN_TOKEN", "Yt-Hahn-Token-Test-1"},
        {"CLICKHOUSE_PASSWORD", "ClickHouse-Pass-Test-1"},
        {"TAKEOUT_TVM_CLIENT_SECRET", "Takeout-TVM-Client-Secret-1"},
        {"TAKEOUT_TVM_CLIENT_SECRET_TESTING", "Takeout-TVM-Client-Secret-1"},
        {"EYE_TVM_CLIENT_SECRET", "EYE-TVM-Client-Secret-1"},
        {"EYE_TVM_CLIENT_SECRET_TESTING", "EYE-TVM-Client-Secret-1"},
        {"NIRVANA_AUTH_TOKEN", "Nirvana-Auth-Token-Test-1"},
        {"NEXAR_REFRESH_TOKEN", "Nexar-Tests"},
    };
    const std::string prefix = SRC_("../cfg");
    const auto ALL_CONFIG_FILES = {
        prefix + "/t-config.unittest.xml",
        prefix + "/t-config.testing.xml",
        prefix + "/t-config.consumer_testing.xml",
        prefix + "/t-config.load.xml",
        prefix + "/t-config.production.xml"
    };
    for (const auto& file: ALL_CONFIG_FILES) {
        Config cfg{ctx, file};
        SCOPED_TRACE(file);
        EXPECT_THAT(cfg.externals().yt().token(), "Yt-Hahn-Token-Test-1");
        EXPECT_THAT(cfg.crowdPlatformConfig(db::toloka::Platform::Toloka).authHeader(), "Toloka-Auth-Header-Test-1");
        EXPECT_THAT(cfg.externals().clickHouseConfig().password(), "ClickHouse-Pass-Test-1");
        EXPECT_THAT(cfg.externals().nirvana().oauthToken(), "Nirvana-Auth-Token-Test-1");
        EXPECT_NO_THROW(cfg.makePoolHolder(CORE_DB_ID, CORE_POOL_ID));
        EXPECT_NO_THROW(cfg.makePoolHolder(LONG_READ_DB_ID, LONG_READ_POOL_ID));
        EXPECT_THROW(cfg.makePoolHolder("blah-blah-blah", "blah-blah-blah"), maps::Exception);
    }
}

TEST(Config_should, read_templated_unittest_config) {
    vault_boy::MemoryContext ctx{
        {"POSTGRESQL_PASSWORD", "Db-Pass-Test-2"},
        {"POSTGRESQL_PASSWORD_TESTING", "Db-Pass-Test-2"},
        {"MDS_AUTH_HEADER", "Mds-Auth-Header-Test-2"},
        {"MDS_AUTH_HEADER_TESTING", "Mds-Auth-Header-Test-2"},
        {"MDS_PUBLIC_AUTH_HEADER", "Mds-Public-Auth-Header-Test-2"},
        {"MDS_PUBLIC_AUTH_HEADER_TESTING", "Mds-Public-Auth-Header-Test-2"},
        {"TOLOKA_AUTH_HEADER", "Toloka-Auth-Header-Test-2"},
        {"TOLOKA_AUTH_HEADER_TESTING", "Toloka-Auth-Header-Test-2"},
        {"YANG_AUTH_HEADER", "Yang-Auth-Header"},
        {"YT_HAHN_TOKEN", "Yt-Hahn-Token-Test-2"},
        {"CLICKHOUSE_PASSWORD", "ClickHouse-Pass-Test-2"},
        {"TAKEOUT_TVM_CLIENT_SECRET", "Takeout-TVM-Client-Secret-2"},
        {"TAKEOUT_TVM_CLIENT_SECRET_TESTING", "Takeout-TVM-Client-Secret-2"},
        {"EYE_TVM_CLIENT_SECRET", "EYE-TVM-Client-Secret-2"},
        {"EYE_TVM_CLIENT_SECRET_TESTING", "EYE-TVM-Client-Secret-2"},
        {"NIRVANA_AUTH_TOKEN", "Nirvana-Auth-Token-Test-2"},
    };
    Config cfg{ctx, ServiceRole::DataGenerator};

    EXPECT_THAT(cfg.rideReportsEmailAddress(), "maps-mrc-rides-reports-dev@yandex-team.ru");

    const auto& extConf = cfg.externals();
    EXPECT_THAT(extConf.nmapsUrl().host(), "nmaps.tst.maps.yandex.ru");
    EXPECT_THAT(extConf.blackboxUrl().host(), "localhost");
    EXPECT_THAT(extConf.socialBackofficeUrl().host(), "localhost");
    EXPECT_THAT(extConf.mrcBrowserUrl().host(), "localhost");
    EXPECT_THAT(extConf.mrcBrowserProUrl().host(), "localhost-pro");
    EXPECT_THAT(extConf.yavisionUrl().host(), "localhost");
    EXPECT_THAT(extConf.mapsCoreUgcBackofficeUrl().host(), "localhost");
    ASSERT_TRUE(extConf.ecstaticEnvironmentOverride().has_value());
    EXPECT_THAT(extConf.ecstaticEnvironmentOverride().value(), maps::common::Environment::Datatesting);
    EXPECT_THAT(extConf.firmwareUpdaterHost(), "core-firmware-updater.testing.maps.yandex.net");
    EXPECT_THAT(extConf.wikiEditorHost(), "core-nmaps-editor.common.testing.maps.yandex.net");
    EXPECT_THAT(extConf.geosearchUrl().host(), "addrs-testing.search.yandex.net");

    const auto& ytConf = extConf.yt();
    EXPECT_THAT(ytConf.token(), "Yt-Hahn-Token-Test-2");
    EXPECT_THAT(ytConf.cluster(), "hahn");
    EXPECT_THAT(ytConf.path(), "//home/maps/core/mrc/tests");

    const auto& mdsConf = cfg.makeMdsConfiguration();
    EXPECT_THAT(mdsConf.writeHost(), "storage-int.mdst.yandex.net");
    EXPECT_THAT(mdsConf.readHost(), "storage-int.mdst.yandex.net");
    EXPECT_THAT(mdsConf.namespaceName(), "maps_mrc");
    EXPECT_THAT(mdsConf.pathPrefix(), "unittest");

    const auto& mdsPubConf = cfg.makePublicMdsConfiguration();
    EXPECT_THAT(mdsPubConf.writeHost(), "storage-int.mdst.yandex.net");
    EXPECT_THAT(mdsPubConf.readHost(), "storage.mdst.yandex.net");
    EXPECT_THAT(mdsPubConf.namespaceName(), "maps_mrc_public");
    EXPECT_THAT(mdsPubConf.pathPrefix(), "unittest");

    const auto& tolokaConf = cfg.crowdPlatformConfig(db::toloka::Platform::Toloka);
    EXPECT_THAT(tolokaConf.host(), "sandbox.toloka");
    EXPECT_THAT(tolokaConf.authHeader(), "Toloka-Auth-Header-Test-2");

    const auto& taskConf2 = tolokaConf.taskConfig(db::toloka::TaskType::Taxonomy);
    ASSERT_TRUE(taskConf2.has_value());
    EXPECT_THAT(taskConf2->templatePoolId(), "0");
    EXPECT_THAT(taskConf2->poolSize(), 3u);
    EXPECT_THAT(taskConf2->suiteSize(), 3u);
    EXPECT_THAT(taskConf2->goldenTasksCount(), 0u);

    const auto& yangConf = cfg.crowdPlatformConfig(db::toloka::Platform::Yang);
    EXPECT_THAT(yangConf.host(), "sandbox.yang");
    EXPECT_THAT(yangConf.authHeader(), "Yang-Auth-Header");

    const auto& upConf = cfg.signalsUploader();
    EXPECT_THAT(upConf.queuePath(), "signals-queue");

    const auto& clickHouseConf = extConf.clickHouseConfig();
    EXPECT_THAT(clickHouseConf.password(), "ClickHouse-Pass-Test-2");
    EXPECT_THAT(clickHouseConf.user(), "robot-maps-core-mrc");
    EXPECT_THAT(clickHouseConf.database(), "maps_mrc");
    EXPECT_THAT(clickHouseConf.readHost(), "http://localhost/");
    EXPECT_THAT(clickHouseConf.writeHosts().size(), 2u);
    EXPECT_THAT(clickHouseConf.writeHosts()[0], "http://localhost/");
    EXPECT_THAT(clickHouseConf.writeHosts()[1], "127.0.0.1");

    const auto& takeoutConf = extConf.takeoutConfig();
    EXPECT_THAT(takeoutConf.ownTvmServiceId(), 0);
    EXPECT_THAT(takeoutConf.dstTvmServiceId(), 0);
    EXPECT_THAT(takeoutConf.tvmSecret(), "unused");
    EXPECT_THAT(takeoutConf.url().toString(), "http://localhost");

    const auto& nirvanaConf = extConf.nirvana();
    EXPECT_THAT(nirvanaConf.oauthToken(), "Nirvana-Auth-Token-Test-2");

    const auto& taxiImportConf = cfg.taxiImportConfig();
    EXPECT_THAT(taxiImportConf.ytCluster(), "hahn");
    EXPECT_THAT(taxiImportConf.ytEventsPath(), "//home/taxi/test-events");
    EXPECT_THAT(taxiImportConf.ytTracksPath(), "//home/taxi/test-tracks");
    EXPECT_THAT(taxiImportConf.ytToken(), "Yt-Hahn-Token-Test-2");

    const auto& nexar = extConf.nexar();
    EXPECT_EQ(nexar.host(), "nexar.com");
    EXPECT_EQ(nexar.refreshToken(), "NEXAR_AUTH_TOKEN");

    const auto& wikiAcl = extConf.wikiAcl();
    EXPECT_EQ(wikiAcl.host(), "core-nmaps-acl.maps.yandex.net");
    EXPECT_EQ(wikiAcl.tvmId(), 111);
}

} // namespace maps::mrc::common::tests
