#pragma once

#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/storage/lib/configuration.h>
#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/storage/lib/error_reporter.h>
#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/libs/unittest/include/database_fixture.h>

#include <library/cpp/testing/gtest/gtest.h>
#include <library/cpp/testing/unittest/env.h>

namespace maps::fw_updater::storage::tests {

class PatchS3ConfigFixture
{
public:
    explicit PatchS3ConfigFixture(xml3::Doc& configDoc)
    {
        auto port = std::getenv("S3MDS_PORT");
        auto node = configDoc.node("/config/s3/client");
        node.setAttr("host", std::string("127.0.0.1:") + port);
    }
};

inline unittest::WithUnittestConfig<unittest::DatabaseFixture, PatchS3ConfigFixture>& playground()
{
    static unittest::WithUnittestConfig<unittest::DatabaseFixture, PatchS3ConfigFixture> global{};
    return global;
}

class Fixture : public testing::Test
{
public:
    Fixture()
    {
        playground().postgres().truncateTables();
        insertData();
        Configuration::swap(std::make_unique<Configuration>(playground().config()));
        configuration()->s3Client().createBucket();

        yacare::setErrorReporter(errorReporter);
    }

    const config::Config& config() const { return playground().config(); }

    pgpool3::Pool& pgPool() { return playground().pool(); }

    pgpool3::TransactionHandle txnHandle()
    {
        return pgPool().masterWriteableTransaction();
    }

private:
    void insertData()
    {
        auto txn = txnHandle();
        txn->exec(maps::common::readFileToString(SRC_("data.sql")));
        txn->commit();
    }
};

} // namespace maps::fw_updater::storage::tests
