//
// Copyright © 2017, 2021-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
#pragma once

#include <armnnTestUtils/PredicateResult.hpp>

#include <armnn/Tensor.hpp>
#include <armnn/utility/Assert.hpp>
#include <armnnUtils/FloatingPointComparison.hpp>

#include <armnnUtils/QuantizeHelper.hpp>

#include <doctest/doctest.h>

#include <array>
#include <cmath>
#include <random>
#include <vector>

constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f;

template<typename T, bool isQuantized = true>
struct SelectiveComparer
{
    static bool Compare(T a, T b)
    {
        return (std::max(a, b) - std::min(a, b)) <= 1;
    }

};

template<typename T>
struct SelectiveComparer<T, false>
{
    static bool Compare(T a, T b)
    {
        // If a or b is zero, percent_tolerance does an exact match, so compare to a small, constant tolerance instead.
        if (a == 0.0f || b == 0.0f)
        {
            return std::abs(a - b) <= g_FloatCloseToZeroTolerance;
        }

        if (std::isinf(a) && a == b)
        {
            return true;
        }

        if (std::isnan(static_cast<float>(a)) && std::isnan(static_cast<float>(b)))
        {
            return true;
        }

        // For unquantized floats we use a tolerance of 1%.
        return armnnUtils::within_percentage_tolerance(a, b);
    }
};

template<typename T>
bool SelectiveCompare(T a, T b)
{
    return SelectiveComparer<T, armnn::IsQuantizedType<T>()>::Compare(a, b);
};

template<typename T>
bool SelectiveCompareBoolean(T a, T b)
{
    return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));
};

template <typename T>
armnn::PredicateResult CompareTensors(const std::vector<T>& actualData,
                                      const std::vector<T>& expectedData,
                                      const armnn::TensorShape& actualShape,
                                      const armnn::TensorShape& expectedShape,
                                      bool compareBoolean = false,
                                      bool isDynamic = false)
{
    if (actualData.size() != expectedData.size())
    {
        armnn::PredicateResult res(false);
        res.Message() << "Different data size ["
                      << actualData.size()
                      << "!="
                      << expectedData.size()
                      << "]";
        return res;
    }

    // Support for comparison between empty tensors
    if (actualData.size() == 0 && expectedData.size() == 0)
    {
        armnn::PredicateResult comparisonResult(true);
        return comparisonResult;
    }

    if (actualShape.GetNumDimensions() != expectedShape.GetNumDimensions())
    {
        armnn::PredicateResult res(false);
        res.Message() << "Different number of dimensions ["
                      << actualShape.GetNumDimensions()
                      << "!="
                      << expectedShape.GetNumDimensions()
                      << "]";
        return res;
    }

    if (actualShape.GetNumElements() != expectedShape.GetNumElements())
    {
        armnn::PredicateResult res(false);
        res.Message() << "Different number of elements ["
                      << actualShape.GetNumElements()
                      << "!="
                      << expectedShape.GetNumElements()
                      << "]";
        return res;
    }

    unsigned int numberOfDimensions = actualShape.GetNumDimensions();

    if (!isDynamic)
    {
        // Checks they are same shape.
        for (unsigned int i = 0; i < numberOfDimensions; ++i)
        {
            if (actualShape[i] != expectedShape[i])
            {
                armnn::PredicateResult res(false);
                res.Message() << "Different shapes ["
                              << actualShape[i]
                              << "!="
                              << expectedShape[i]
                              << "]";
                return res;
            }
        }
    }

    // Fun iteration over n dimensions.
    std::vector<unsigned int> indices;
    for (unsigned int i = 0; i < numberOfDimensions; i++)
    {
        indices.emplace_back(0);
    }

    std::stringstream errorString;
    int numFailedElements = 0;
    constexpr int maxReportedDifferences = 3;
    unsigned int index = 0;

    // Compare data element by element.
    while (true)
    {
        bool comparison;
        // As true for uint8_t is non-zero (1-255) we must have a dedicated compare for Booleans.
        if(compareBoolean)
        {
            comparison = SelectiveCompareBoolean(actualData[index], expectedData[index]);
        }
        else
        {
            comparison = SelectiveCompare(actualData[index], expectedData[index]);
        }

        if (!comparison)
        {
            ++numFailedElements;

            if (numFailedElements <= maxReportedDifferences)
            {
                if (numFailedElements >= 2)
                {
                    errorString << ", ";
                }
                errorString << "[";
                for (unsigned int i = 0; i < numberOfDimensions; ++i)
                {
                    errorString << indices[i];
                    if (i != numberOfDimensions - 1)
                    {
                        errorString << ",";
                    }
                }
                errorString << "]";

                errorString << " (" << +actualData[index] << " != " << +expectedData[index] << ")";
            }
        }

        ++indices[numberOfDimensions - 1];
        for (unsigned int i=numberOfDimensions-1; i>0; i--)
        {
            if (indices[i] == actualShape[i])
            {
                indices[i] = 0;
                ++indices[i - 1];
            }
        }
        if (indices[0] == actualShape[0])
        {
            break;
        }

        index++;
    }

    armnn::PredicateResult comparisonResult(true);
    if (numFailedElements > 0)
    {
        comparisonResult.SetResult(false);
        comparisonResult.Message() << numFailedElements << " different values at: ";
        if (numFailedElements > maxReportedDifferences)
        {
            errorString << ", ... (and " << (numFailedElements - maxReportedDifferences) << " other differences)";
        }
        comparisonResult.Message() << errorString.str();
    }

    return comparisonResult;
}

template <typename T>
std::vector<T> MakeRandomTensor(const armnn::TensorInfo& tensorInfo,
                                unsigned int seed,
                                float        min = -10.0f,
                                float        max = 10.0f)
{
    std::mt19937 gen(seed);
    std::uniform_real_distribution<float> dist(min, max);

    std::vector<float> init(tensorInfo.GetNumElements());
    for (unsigned int i = 0; i < init.size(); i++)
    {
        init[i] = dist(gen);
    }

    const float   qScale  = tensorInfo.GetQuantizationScale();
    const int32_t qOffset = tensorInfo.GetQuantizationOffset();

    return armnnUtils::QuantizedVector<T>(init, qScale, qOffset);
}
