#include "detection_relations.h"

#include <maps/wikimap/mapspro/services/mrc/libs/signdetect/include/detected_sign.h>
#include <maps/wikimap/mapspro/services/mrc/libs/signdetect/include/sign_relations.h>

#include <functional>

namespace maps::mrc::eye {

namespace {

using DetectionCRef = std::reference_wrapper<const db::eye::Detection>;

signdetect::DetectedSign convertToDetectedSign(
    const db::eye::Frame& frame, const db::eye::DetectedSign& input)
{
    signdetect::DetectedSign output;
    output.box = common::transformByImageOrientation(
        input.box, frame.originalSize(), frame.orientation());
    output.sign = input.type;
    output.confidence = input.typeConfidence;
    output.temporarySign = input.temporary ? traffic_signs::TemporarySign::Yes
                                           : traffic_signs::TemporarySign::No;
    output.temporarySignConfidence = input.temporaryConfidence;
    return output;
}

signdetect::DetectedSigns convertToDetectedSigns(
    const db::eye::Frame& frame, const db::eye::Detections& detections)
{
    signdetect::DetectedSigns results;
    for (const auto& detection: detections) {
        REQUIRE(!detection.deleted(),
            "Detection " << detection.id() << " is deleted but must not be");
        results.emplace_back(convertToDetectedSign(
            frame, detection.attrs<db::eye::DetectedSign>()));
    }
    return results;
}

} // namespace

db::eye::DetectionRelations findSignDetectionRelations(
    const db::eye::Frame& frame, const db::eye::Detections& detections)
{
    db::eye::DetectionRelations relations;
    signdetect::DetectedSigns detectedSigns =
        convertToDetectedSigns(frame, detections);
    std::vector<std::pair<size_t, size_t>> relIndices =
        signdetect::foundRelations(detectedSigns);
    for (auto [first_idx, second_idx]: relIndices) {
        relations.emplace_back(
            detections[second_idx].id(), detections[first_idx].id());
    }
    return relations;
}

} // namespace maps::mrc::eye
