#include <maps/wikimap/mapspro/services/mrc/libs/coord_recognition/include/coord_recognition.h>

#include <library/cpp/testing/common/env.h>
#include <library/cpp/testing/gtest/gtest.h>
#include <maps/libs/common/include/exception.h>
#include <maps/libs/common/include/file_utils.h>

#include <opencv2/opencv.hpp>

#include <vector>

using namespace testing;

namespace maps {
namespace mrc {
namespace coord_recognition {

namespace tests {

namespace {

using TestDataPair = std::pair<std::string, Coordinates>;

const std::vector<TestDataPair> TEST_DATA =
{
    {"000000.png", {56.7834f, 36.0274f, 0.0f}},
    {"000001.png", {56.7684f, 36.1480f, 0.0f}},
    {"000002.png", {56.8910f, 35.7412f, 0.0f}},
    {"000003.png", {56.9615f, 35.3492f, 0.0f}},
    {"000004.png", {57.4821f, 34.6836f, 0.0f}},
    {"000099.png", {52.7250f, 35.8146f, 0.0f}}
};

cv::Mat loadImage(const std::string& name, int flags) {
    static const std::string IMAGES_DIR =
        "maps/wikimap/mapspro/services/mrc/libs/coord_recognition/tests/images/";
    auto imagePath = static_cast<std::string>(BinaryPath(IMAGES_DIR + name));
    cv::Mat image = cv::imread(imagePath, flags);
    REQUIRE(image.data != nullptr, "Can't load image " << name);
    return image;
}

} // namespace

TEST(basic_tests, coord_recognition_on_reference_images)
{
    constexpr float MAX_DIST_ERROR = 0.0001f;

    maps::mrc::coord_recognition::CoordRecognition recog;
    for (size_t i = 0; i < TEST_DATA.size(); i++){
        cv::Mat image = loadImage(TEST_DATA[i].first, cv::IMREAD_COLOR);
        Coordinates result = recog.recognize(image);
        float dist = sqrtf(
            (TEST_DATA[i].second.first - result.first) * (TEST_DATA[i].second.first - result.first) +
            (TEST_DATA[i].second.second - result.second) * (TEST_DATA[i].second.second - result.second)
        );
        EXPECT_LT(dist, MAX_DIST_ERROR);
    }
}

} // namespace test

} // namespace coord_recognition
} // namespace mrc
} // namespace maps
