#include "rotation_classifier.h"

#include <library/cpp/resource/resource.h>
#include <opencv2/imgcodecs/imgcodecs_c.h>
#include <maps/libs/log8/include/log8.h>

namespace maps::mrc::classifiers {

namespace {

const std::string ROTATION_CLASSIFIER_RESOURCE_KEY
    = "/maps/mrc/classifiers/models/rotation_classifier.gdef";

} // anonymous namespace

RotationClassifier::RotationClassifier()
    : TensorFlowClassifier(
        wiki::tf_inferencer::TensorFlowInferencer::fromResource(
          ROTATION_CLASSIFIER_RESOURCE_KEY
        )
    )
{}

common::ImageOrientation RotationClassifier::detectImageOrientation(const common::Blob& encodedImage) const
{
    return detectImageOrientation(common::toBytes(encodedImage));
}

common::ImageOrientation RotationClassifier::detectImageOrientation(const cv::Mat& image) const
{
    const auto orientation = callClassifier(image).first;

    using Rotation = common::Rotation;

    if (orientation == "0_degrees") {
        return {false, Rotation::CW_0};
    } else if (orientation == "90_degrees") {
        return {false, Rotation::CW_90};
    } else if (orientation == "180_degrees") {
        return {false, Rotation::CW_180};
    } else if (orientation == "270_degrees") {
        return {false, Rotation::CW_270};
    }

    throw Exception() << "Unknown rotation: " << orientation;
}


common::ImageOrientation RotationClassifier::detectImageOrientation(
        const common::Bytes& encodedImage) const
{
    const auto result = common::parseImageOrientationFromExif(encodedImage);
    if (result) {
        return *result;
    }

    return detectImageOrientation(common::decodeImage(encodedImage));
}

} // namespace maps::mrc::classifiers
