#include "object_manager_fixture.h"


namespace maps::mrc::eye::tests {


ObjectManagerFixture::ObjectManagerFixture()
    : loader(FrameLoader::fromConfig(config()))
{}


bool ObjectManagerFixture::checkObjectRelations(
    db::TId primaryId, db::TIds detectionIds) const
{
    namespace table = db::eye::table;

    const auto relations =
        db::eye::PrimaryDetectionRelationGateway(*newTxn()).load(
            not table::PrimaryDetectionRelation::deleted and
            (table::PrimaryDetectionRelation::primaryDetectionId ==
                    primaryId or
                table::PrimaryDetectionRelation::primaryDetectionId.in(
                    detectionIds) or
                table::PrimaryDetectionRelation::detectionId.in(detectionIds)));

    db::TIds resultIds;
    for (const auto& relation: relations) {
        resultIds.push_back(relation.detectionId());
    }

    std::sort(detectionIds.begin(), detectionIds.end());
    std::sort(resultIds.begin(), resultIds.end());

    return detectionIds == resultIds and
            std::all_of(
                relations.begin(), relations.end(), [&](const auto& relation) {
                    return relation.primaryDetectionId() == primaryId and
                            relation.txnId() >
                                0; // simple check instead of direct
                });
}

bool ObjectManagerFixture::checkObject(db::TId primaryId, bool deleted) const
{
    ASSERT(primaryId);

    namespace table = db::eye::table;

    const auto object = db::eye::ObjectGateway(*newTxn()).loadOne(
        table::Object::primaryDetectionId == primaryId);

    return object.deleted() == deleted and object.disappearedAt().has_value() == false and
            object.txnId() > 0;
}

bool ObjectManagerFixture::checkObjectLocation(
    db::TId primaryId, const Location& expected) const
{
    ASSERT(primaryId);

    namespace table = db::eye::table;

    const auto location = db::eye::ObjectLocationGateway(*newTxn()).loadOne(
        table::Object::primaryDetectionId == primaryId and
        table::Object::id == table::ObjectLocation::objectId);

    return location.txnId() > 0 and
            not areDifferent(
                location,
                expected,
                ObjectManager::POSITION_TOLERANCE_METERS,
                ObjectManager::ROTATION_TOLERANCE);
}



} // namespace maps::mrc::eye::tests
