#include "important_regions.h"
#include <maps/wikimap/mapspro/libs/validator/common/utils.h>

#include <yandex/maps/wiki/validator/common.h>

#include <yandex/maps/wiki/common/retry_duration.h>
#include <yandex/maps/wiki/revision/revisionsgateway.h>
#include <yandex/maps/wiki/revision/branch_manager.h>

#include <maps/libs/geolib/include/bounding_box.h>

namespace mwrev = maps::wiki::revision;
namespace rf = maps::wiki::revision::filters;

namespace maps::wiki::validator {

namespace {

const std::string CAT_DIFFALERT_REGION = "cat:diffalert_region";

} // namespace

ImportantRegions::ImportantRegions(
    DBGateway& gateway,
    const AreaOfInterest& aoi)
{
    if (!gateway.commitId()) {
        return;
    }

    Timer timer;

    auto revisionFilter = rf::ProxyFilterExpr(
        rf::Attr(CAT_DIFFALERT_REGION).defined()
        && rf::ObjRevAttr::isNotRelation()
        && rf::ObjRevAttr::isNotDeleted()
        && rf::Geom::defined());

    if (!aoi.empty() && aoi.boundingBox()) {
        const auto& bbox = *aoi.boundingBox();
        revisionFilter &= rf::GeomFilterExpr(
            rf::GeomFilterExpr::Operation::IntersectsPolygons,
            bbox.minX(), bbox.minY(), bbox.maxX(), bbox.maxY());
    }

    auto revisions = common::retryDuration([&] {
        auto txn = gateway.getTransaction();
        auto revIds = gateway.revisionIdsByFilter(revisionFilter, *txn);
        return gateway.revisionsByRevisionIds(revIds, true, *txn);
    });

    for (const auto& rev : revisions) {
        REQUIRE(rev.data().geometry, "Object " << rev.id() << " has no geometry");
        regions_.emplace_back(geolib3::WKB::read<geolib3::Polygon2>(*rev.data().geometry));
    }

    INFO() << "important regions loaded in " << timer.elapsed().count() << "s.";
}

} // namespace maps::wiki::validator
