//
// Copyright © 2017 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 <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(a) && std::isnan(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;
    }

    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);
}
