#include <yandex/maps/mrc/unittest/database_fixture.h>

#include <maps/libs/config/include/config.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/xml/include/xml.h>

#include <library/cpp/testing/common/env.h>

#include <mutex>

namespace maps {
namespace mrc {
namespace unittest {

namespace {

const std::string MRC_MIGRATIONS_PATH = (
    ArcadiaSourceRoot() +
    "/maps/wikimap/mapspro/services/mrc/migrations/migrations"
);

} // anonymous namespace

DatabaseFixture::DatabaseFixture(xml3::Doc& configDoc)
    : postgres_(blankDb().clone())
{
    const std::string DATABASE_XPATH = "/config/common/databases/database";

    auto databases = configDoc.nodes(DATABASE_XPATH);
    for (size_t i = 0; i < databases.size(); ++i) {
        auto database = databases[i];
        database.setAttr("name", postgres_.dbname());
    }
    auto hosts = configDoc.nodes(DATABASE_XPATH + "/host");
    for (size_t i = 0; i < hosts.size(); ++i) {
        auto host = hosts[i];
        host.setAttr("host", postgres_.host());
        host.setAttr("port", std::to_string(postgres_.port()));
        host.setAttr("user", postgres_.user());
        host.setAttr("password", postgres_.password());
    }
    sharedPool_ = std::make_shared<wiki::common::PoolHolder>(
        configDoc.node(DATABASE_XPATH + "[@id='" + common::CORE_DB_ID + "']"),
        common::CORE_DB_ID,
        common::CORE_POOL_ID);
    INFO() << "Testing MRC DB connection string: '" << connStr() << "'";
}

pgpool3::Pool& DatabaseFixture::pool()
{
    return sharedPool_->pool();
}

common::SharedPool DatabaseFixture::sharedPool()
{
    return sharedPool_;
}

std::string DatabaseFixture::connStr() const
{
    return postgres_.connectionString();
}

local_postgres::Database& DatabaseFixture::blankDb() {
    static std::once_flag flag;
    static local_postgres::Database db;

    char* envPath = std::getenv("MRC_MIGRATIONS_PATH");

    const std::string migrationsPath =
        envPath ? std::string(envPath) : MRC_MIGRATIONS_PATH;

    std::call_once(flag, [&]{
        db.createExtension("postgis");
        db.createExtension("pg_trgm");
        db.runPgMigrate(migrationsPath);
    });
    return db;
}

} // unittest
} // mrc
} // maps
