#include "quality_classifier.h"

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

namespace maps::mrc::classifiers {

namespace {

const std::string QUALITY_CLASSIFIER_RESOURCE_KEY
    = "/maps/mrc/classifiers/models/quality_classifier.gdef";

} // anonymous namespace

QualityClassifier::QualityClassifier()
    : TensorFlowClassifier{
        wiki::tf_inferencer::TensorFlowInferencer::fromResource(
            QUALITY_CLASSIFIER_RESOURCE_KEY
        )
    }
{}

double QualityClassifier::estimateImageQuality(const cv::Mat& image) const
{
    if (isImageHomogeneous(image)) {
        return 0.0;
    }

    const auto result = callClassifier(image);

    if (result.first == "bad_quality") {
        return 1. - result.second;
    } else if (result.first == "good_quality") {
        return result.second;
    }

    throw Exception() << "Unknown quality: " << result.first;
}

double QualityClassifier::estimateImageQuality(const common::Bytes& decodeImage) const
{
    return estimateImageQuality(common::decodeImage(decodeImage));
}

double QualityClassifier::estimateImageQuality(const common::Blob& decodeImage) const
{
    return estimateImageQuality(common::decodeImage(decodeImage));
}

bool QualityClassifier::isImageHomogeneous(const cv::Mat& image) const
{
    constexpr double THRESHOLD = 20.;

    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

    double minVal = 0;
    double maxVal = 0;

    cv::minMaxIdx(gray, &minVal, &maxVal);

    return maxVal - minVal < THRESHOLD;
}

} // namespace maps::mrc::classifiers
