#include "object_helpers.h"

#include <yandex/maps/wiki/common/compound_token.h>
#include <maps/libs/geolib/include/serialization.h>
#include <maps/libs/geolib/include/variant.h>
#include <maps/libs/log8/include/log8.h>

namespace maps::wiki::renderer_overlay {

namespace {

// TODO: Move this code taken from editor branch helpers to common lib

const std::string VREVISIONS_PREFIX = "vrevisions_";
const std::string VREVISIONS_TRUNK = VREVISIONS_PREFIX + "trunk";
const std::string VREVISIONS_STABLE_PREFIX = VREVISIONS_PREFIX + "stable_";

std::string
vrevisionsSchemaName(revision::DBID branchId)
{
    if (branchId == revision::TRUNK_BRANCH_ID) {
        return VREVISIONS_TRUNK;
    }
    return VREVISIONS_STABLE_PREFIX + std::to_string(branchId);
}

void
setSearchPath(pqxx::transaction_base& work, revision::DBID branchId)
{
    work.exec("SET search_path=" + vrevisionsSchemaName(branchId) + ",public");
}

std::string aliasView(revision::DBID branchId)
{
    return common::CompoundToken::alias(branchId);
}

std::string
getViewToken(revision::DBID branchId, const std::string& token)
{
    return common::CompoundToken::subToken(token, aliasView(branchId));
}

} // namespace

std::optional<geolib3::Polygon2>
getObjectGeometry(
    pgpool3::Pool& pool,
    revision::DBID branchId,
    const std::string& token,
    revision::DBID objectId)
{
    auto txn = pool.slaveTransaction(getViewToken(branchId, token));
    setSearchPath(*txn, branchId);
    const auto row = txn->exec(
        "SELECT ST_AsBinary(the_geom) "
        "FROM objects_a_view WHERE id=" + std::to_string(objectId));
    if (row.empty()) {
        return std::nullopt;
    }
    try {
        const auto variant =
            geolib3::WKB::read<geolib3::SimpleGeometryVariant>(
                    txn->unesc_raw(row[0][0].c_str()));
        REQUIRE(geolib3::GeometryType::Polygon == variant.geometryType(),
            "Requested object geometry type is not polygon: " << objectId);
        return variant.get<geolib3::Polygon2>();
    } catch (const maps::Exception& ex) {
        WARN() << "Error while retrieving geom: " << ex;
    }
    return std::nullopt;
}
} // namespace maps::wiki::renderer_overlay
