#include "new_objects_with_ft_type_counter.h"

#include "utils.h"

#include <yandex/maps/wiki/revision/filters.h>
#include <yandex/maps/wiki/revision/revisionsgateway.h>

namespace rev = maps::wiki::revision;
namespace filter = maps::wiki::revision::filters;

namespace maps::wiki::tasks::involvement {
namespace {
const std::string FT_TYPE_SUFFIX = ":ft_type_id";
bool
isOneOfFtType(const revision::ObjectRevision& objRev, const std::set<std::string>& ftTypes)
{
    const auto& data = objRev.data();
    if (!data.attributes) {
        return false;
    }
    const auto& attrs = *data.attributes;
    for (const auto& [id, val] : attrs) {
        if (id.ends_with(FT_TYPE_SUFFIX)) {
            return ftTypes.contains(val);
        }
    }
    return false;
}

} // namespace

NewObjectsWithFtTypeCounter::NewObjectsWithFtTypeCounter(
    std::vector<revision::DBID> commitIds,
    pqxx::transaction_base& coreTxn,
    std::string objectCategory,
    std::set<std::string> ftTypes)
    : ICommitsCounter(std::move(commitIds))
    , coreTxn_(coreTxn)
    , objectCategory_(std::move(objectCategory))
    , ftTypes_(std::move(ftTypes))
{}

int64_t NewObjectsWithFtTypeCounter::countImpl(
    const geolib3::MultiPolygon2& polygons)
{
    rev::RevisionsGateway gateway(coreTxn_);

    auto geosMultiPolygon = polygons.polygonsNumber() ?
        geolib3::internal::geolib2geosGeometry(polygons) :
        nullptr;

    auto filter = (
        filter::Attr(objectCategory_).defined() &&
        filter::ObjRevAttr::prevCommitId().isZero() &&
        filter::ObjRevAttr::isNotDeleted() &&
        filter::ObjRevAttr::isNotRelation() &&
        filter::CommitAttr::id().in(commitIds_) &&
        filter::Geom::defined()
    );
    auto revisions = gateway.reader().loadRevisions(filter);
    revisions.remove_if([&]
        (const auto& rev) {
            return !isOneOfFtType(rev, ftTypes_);
        });
    return countObjectsInsideRegion(
        revisions,
        geosMultiPolygon
    );
}
} // namespace maps::wiki::tasks::involvement
