//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include "InferenceTestImage.hpp"
#include "ObjectDetectionCommon.hpp"

#include <QuantizeHelper.hpp>

#include <armnn/TypesUtils.hpp>

#include <boost/log/trivial.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <array>
#include <memory>
#include <string>
#include <vector>

namespace
{

struct MobileNetSsdTestCaseData
{
    MobileNetSsdTestCaseData(
        const std::vector<uint8_t>& inputData,
        const std::vector<DetectedObject>& expectedDetectedObject,
        const std::vector<std::vector<float>>& expectedOutput)
        : m_InputData(inputData)
        , m_ExpectedDetectedObject(expectedDetectedObject)
        , m_ExpectedOutput(expectedOutput)
    {}

    std::vector<uint8_t>            m_InputData;
    std::vector<DetectedObject>     m_ExpectedDetectedObject;
    std::vector<std::vector<float>> m_ExpectedOutput;
};

class MobileNetSsdDatabase
{
public:
    explicit MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset);

    std::unique_ptr<MobileNetSsdTestCaseData> GetTestCaseData(unsigned int testCaseId);

private:
    std::string m_ImageDir;
    float m_Scale;
    int m_Offset;
};

constexpr unsigned int k_MobileNetSsdImageWidth  = 300u;
constexpr unsigned int k_MobileNetSsdImageHeight = k_MobileNetSsdImageWidth;

// Test cases
const std::array<ObjectDetectionInput, 1> g_PerTestCaseInput =
{
    ObjectDetectionInput
    {
        "Cat.jpg",
        {
          DetectedObject(16.0f, BoundingBox(0.216785252f, 0.079726994f, 0.927124202f, 0.939067304f), 0.79296875f)
        }
    }
};

MobileNetSsdDatabase::MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset)
    : m_ImageDir(imageDir)
    , m_Scale(scale)
    , m_Offset(offset)
{}

std::unique_ptr<MobileNetSsdTestCaseData> MobileNetSsdDatabase::GetTestCaseData(unsigned int testCaseId)
{
    const unsigned int safeTestCaseId =
        testCaseId % boost::numeric_cast<unsigned int>(g_PerTestCaseInput.size());
    const ObjectDetectionInput& testCaseInput = g_PerTestCaseInput[safeTestCaseId];

    // Load test case input
    const std::string imagePath = m_ImageDir + testCaseInput.first;
    std::vector<uint8_t> imageData;
    try
    {
        InferenceTestImage image(imagePath.c_str());

        // Resize image (if needed)
        const unsigned int width  = image.GetWidth();
        const unsigned int height = image.GetHeight();
        if (width != k_MobileNetSsdImageWidth || height != k_MobileNetSsdImageHeight)
        {
            image.Resize(k_MobileNetSsdImageWidth, k_MobileNetSsdImageHeight, CHECK_LOCATION());
        }

        // Get image data as a vector of floats
        std::vector<float> floatImageData = GetImageDataAsNormalizedFloats(ImageChannelLayout::Rgb, image);
        imageData = armnnUtils::QuantizedVector<uint8_t>(floatImageData, m_Scale, m_Offset);
    }
    catch (const InferenceTestImageException& e)
    {
        BOOST_LOG_TRIVIAL(fatal) << "Failed to load image for test case " << testCaseId << ". Error: " << e.what();
        return nullptr;
    }

    std::vector<float> numDetections = { static_cast<float>(testCaseInput.second.size()) };

    std::vector<float> detectionBoxes;
    std::vector<float> detectionClasses;
    std::vector<float> detectionScores;

    for (DetectedObject expectedObject : testCaseInput.second)
    {
            detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMin);
            detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMin);
            detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMax);
            detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMax);

            detectionClasses.push_back(expectedObject.m_Class);

            detectionScores.push_back(expectedObject.m_Confidence);
    }

    // Prepare test case expected output
    std::vector<std::vector<float>> expectedOutputs;
    expectedOutputs.reserve(4);
    expectedOutputs.push_back(detectionBoxes);
    expectedOutputs.push_back(detectionClasses);
    expectedOutputs.push_back(detectionScores);
    expectedOutputs.push_back(numDetections);

    return std::make_unique<MobileNetSsdTestCaseData>(imageData, testCaseInput.second, expectedOutputs);
}

} // anonymous namespace
