#include <maps/wikimap/mapspro/services/mrc/eye/lib/common/include/secure_config.h>

#include <mapreduce/yt/interface/operation.h>

namespace maps::mrc::eye {
namespace {

const TString MRC_CONFIG = "mrc_config";

volatile SecureConfig* g_secureConfig = nullptr;

} // namespace

void SecureConfig::initialize(std::optional<common::Config> mrcConfig)
{
    const auto getMrcConfig = [&] {
        if (!mrcConfig) {
            // Being here means being executed on YT node.
            const auto secureVault = NYT::GetJobSecureVault();

            REQUIRE(!secureVault.IsUndefined(),
                    "Secure config is not initialized for YT job");

            const auto node = secureVault[MRC_CONFIG];
            REQUIRE(!node.IsUndefined(),
                    "Impossible to load mrc config");

            mrcConfig = common::Config::fromString(node.AsString());
        }

        return std::move(*mrcConfig);
    };

    static SecureConfig config{getMrcConfig()};
    g_secureConfig = &config;
}

const SecureConfig& SecureConfig::instance()
{
    if (!g_secureConfig) {
        // The code flow takes this branch for YT jobs.
        SecureConfig::initialize(std::nullopt);
    }
    return const_cast<const SecureConfig&>(*g_secureConfig);
}

bool SecureConfig::isInitialized()
{
    return g_secureConfig != nullptr;
}

SecureConfig::operator NYT::TNode() const {
    return NYT::TNode::CreateMap()(
        MRC_CONFIG, TString(mrcConfig().toString()));
}

const common::Config& SecureConfig::mrcConfig() const
{
    return mrcConfig_;
}

} // namespace maps::mrc::eye
