#pragma once

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

#include <maps/libs/common/include/make_batches.h>

#include "query_generator.h"

namespace maps::wiki::revision::filters {

template<typename Batch>
inline ProxyFilterExpr makeFilterForObjectIdBatch(const Batch& batch)
{
    return ObjRevAttr::objectId().in(batch);
}

template<typename Batch>
inline ProxyFilterExpr makeFilterForMasterObjectIdBatch(const Batch& batch)
{
    return ObjRevAttr::masterObjectId().in(batch);
}

template<typename Batch>
inline ProxyFilterExpr makeFilterForSlaveObjectIdBatch(const Batch& batch)
{
    return ObjRevAttr::slaveObjectId().in(batch);
}

template<typename Batch>
inline ProxyFilterExpr makeFilterForRevisionIdBatch(const Batch& batch)
{
    auto queryData = QueryGenerator::buildCommitIdToObjectIds(
        {batch.begin(), batch.end()}
    );
    filters::ProxyFilterExpr expr(std::make_shared<filters::False>());
    for (const auto& commitObjectIds: queryData.first) {
        expr |=(
            (filters::ObjRevAttr::commitId() == commitObjectIds.first) &&
            filters::ObjRevAttr::objectId().in(commitObjectIds.second)
        );
    }
    return expr;
}

template<typename Batch>
inline ProxyFilterExpr makeFilterForRelationDataBatch(const Batch& batch)
{
    std::map<DBID, DBIDSet> masterToSlaves;
    for (const auto& rel: batch) {
        masterToSlaves[rel.masterObjectId()].insert(rel.slaveObjectId());
    }

    filters::ProxyFilterExpr expr(std::make_shared<filters::False>());
    for (const auto& pair: masterToSlaves) {
        expr |=(
            (filters::ObjRevAttr::masterObjectId() == pair.first) &&
            filters::ObjRevAttr::slaveObjectId().in(pair.second)
        );
    }
    return expr;
}

} // namespace maps::wiki::revision::filters
