#include "detector.h"

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/feature_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/object_in_photo_gateway.h>
#include <maps/wikimap/mapspro/services/mrc/libs/privacy_detector/include/privacy_detector_faster_rcnn.h>
#include <maps/wikimap/mapspro/services/mrc/libs/yt/include/serialization.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/wikimap/mapspro/services/mrc/libs/common/include/exif.h>

#include <opencv2/opencv.hpp>
#include <optional>

namespace maps::mrc::image_analyzer {

using FeatureWithImage = yt::FeatureWithImage<db::Feature>;

void PrivacyObjectsDetector::Do(TReader* reader, TWriter* writer)
{
    privacy_detector::FasterRCNNDetector privacyDetector;

    for (; reader->IsValid(); reader->Next()) {
        const auto& row = reader->GetRow();

        auto [feature, image] = yt::deserialize<FeatureWithImage>(row);

        if (image.empty()) {
            WARN() << "feature " << feature.id() << ": empty image";
            continue;
        }

        cv::Mat normalizedImage = common::transformByImageOrientation(image, feature.orientation());

        privacy_detector::PrivacyImageBoxes privacyObjects = privacyDetector.detect(normalizedImage);
        cv::Rect normalizedImageRect(0, 0, normalizedImage.cols, normalizedImage.rows);
        for (size_t i = 0; i < privacyObjects.size(); i++) {
            const privacy_detector::PrivacyImageBox &privacyObject = privacyObjects[i];
            cv::Rect boxInsideImage = ((cv::Rect)privacyObject.box) & normalizedImageRect;
            if (boxInsideImage.width <= 0 || boxInsideImage.height <= 0)
                continue;
            common::ImageBox box = common::revertByImageOrientation(
                                      common::ImageBox(boxInsideImage),
                                      {(size_t)image.cols, (size_t)image.rows},
                                      feature.orientation());
            db::ObjectInPhoto dbObject(feature.id(), privacyObject.type, box, privacyObject.confidence);
            writer->AddRow(yt::serialize(dbObject));
        }
    }
}


REGISTER_MAPPER(PrivacyObjectsDetector);

} // namespace maps::mrc::image_analyzer
