#include <maps/wikimap/ugc/libs/common/config.h>
#include <maps/libs/common/include/exception.h>
#include <sstream>

namespace maps::wiki::ugc {

namespace {

std::string dbConfig(const maps::json::Value& dbconf)
{
    const std::string& dbname = dbconf["database"].as<std::string>();
    const std::string& user = dbconf["user"].as<std::string>();
    const int port = dbconf["port"].as<int>();
    const std::string& password = dbconf["password"].as<std::string>();
    REQUIRE(dbconf["hosts"].isArray(), "No hosts array in config");

    std::ostringstream result;
    result << "<database>" << " name=\"" << dbname << "\">";
    for (const auto& host :  dbconf["hosts"]) {
        result << "<host"
            << " dbname=\"" << dbname << "\""
            << " host=\"" << host.as<std::string>() << "\""
            << " port=\"" << port << "\""
            << " user=\"" << user << "\""
            << " pass=\"" << password << "\"/>";
    }
    result << "<pool"
        << " timeout=\"" << dbconf["timeout"].as<uint32_t>(10) << "\""
        << " pingPeriod=\"" << dbconf["pingPeriod"].as<uint32_t>(5) << "\""
        << " writePoolOverflow=\"" << dbconf["writePoolOverflow"].as<uint32_t>(4) << "\""
        << " writePoolSize=\"" << dbconf["writePoolSize"].as<uint32_t>(2) << "\""
        << " readPoolSize=\"" << dbconf["readPoolSize"].as<uint32_t>(6) << "\""
        << " readPoolOverflow=\"" << dbconf["readPoolOverflow"].as<uint32_t>(9) << "\""
        << " treatMasterAsSlave=\"1\"/>";
    result << "</database>";

    return result.str();
}

} // namespace

std::vector<std::string> dbConfigsFromJson(const json::Value& config)
{
    REQUIRE(config.hasField("dbs"), "dbs field in config is not found");

    std::vector<std::string> result;
    const auto& dbsConfig = config["dbs"];
    REQUIRE(dbsConfig.isArray(), "dbs field in config is not array");
    for (const auto& dbConf : dbsConfig) {
        result.emplace_back(dbConfig(dbConf));
    }
    return result;
}

} // namespace maps::wiki::ugc
