// Copyright (c) 2023-2024, ARM Limited.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//         http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

#include <cmath>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>

#include "half.hpp"
#include "verifiers.h"
namespace TosaReference
{

namespace
{
template <typename OutType>
double calcErrorBound(double referenceValue, double boundsValue, const void* cfgPtr)
{
    const auto cfg = reinterpret_cast<const AbsErrorVerifyInfo*>(cfgPtr);

    double valBound = std::abs(referenceValue) * boundsValue;
    if (cfg->lowerBound > 0)
    {
        valBound = std::max(cfg->lowerBound, valBound);
    }
    return exp2(-AccPrecision<OutType>::normal_frac / cfg->normalDivisor) * valBound;
}
}    // namespace

bool verifyAbsError(const CTensor* referenceTensor,
                    const CTensor* boundsTensor,
                    const CTensor* implementationTensor,
                    const AbsErrorVerifyInfo& aeInfo)
{
    // Validate that tensors are provided
    TOSA_REF_REQUIRE(referenceTensor != nullptr, "[AE] Reference tensor is missing");
    TOSA_REF_REQUIRE(boundsTensor != nullptr, "[AE] Reference bounds tensor is missing");
    TOSA_REF_REQUIRE(implementationTensor != nullptr, "[AE] Implementation tensor is missing");

    const std::vector<int32_t> refShape(referenceTensor->shape, referenceTensor->shape + referenceTensor->num_dims);

    const double* refData    = reinterpret_cast<const double*>(referenceTensor->data);
    const double* refBndData = reinterpret_cast<const double*>(boundsTensor->data);
    TOSA_REF_REQUIRE(refData != nullptr && refBndData != nullptr, "[AE] Missing data for reference or bounds tensors");

    const std::string modeStr = "AE";

    switch (implementationTensor->data_type)
    {
        case tosa_datatype_fp32_t: {
            const auto* impData = reinterpret_cast<const float*>(implementationTensor->data);
            TOSA_REF_REQUIRE(impData != nullptr, "[AE] Missing data for implementation");
            return validateData(refData, refBndData, impData, refShape, modeStr, &aeInfo, &calcErrorBound<float>);
        }
        case tosa_datatype_fp16_t: {
            const auto* impData = reinterpret_cast<const half_float::half*>(implementationTensor->data);
            TOSA_REF_REQUIRE(impData != nullptr, "[AE] Missing data for implementation");
            return validateData(refData, refBndData, impData, refShape, modeStr, &aeInfo,
                                &calcErrorBound<half_float::half>);
        }
        default:
            WARNING("[Verifier][AE] Data-type not supported.");
            break;
    }

    return false;
}
}    // namespace TosaReference
