/*
 * Copyright (c) 2016, 2017 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_VALIDATE_H__
#define __ARM_COMPUTE_VALIDATE_H__

#include "arm_compute/core/Error.h"
#include "arm_compute/core/HOGInfo.h"
#include "arm_compute/core/IKernel.h"
#include "arm_compute/core/IMultiHOG.h"
#include "arm_compute/core/IMultiImage.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/MultiImageInfo.h"
#include "arm_compute/core/Window.h"

#include <algorithm>

namespace arm_compute
{
namespace detail
{
/* Check whether two dimension objects differ.
 *
 * @param[in] dim1      First object to be compared.
 * @param[in] dim2      Second object to be compared.
 * @param[in] upper_dim The dimension from which to check.
 *
 * @return Return true if the two objects are different.
 */
template <typename T>
inline bool have_different_dimensions(const Dimensions<T> &dim1, const Dimensions<T> &dim2, unsigned int upper_dim)
{
    for(unsigned int i = upper_dim; i < arm_compute::Dimensions<T>::num_max_dimensions; ++i)
    {
        if(dim1[i] != dim2[i])
        {
            return true;
        }
    }

    return false;
}

/** Functor to compare two @ref Dimensions objects and throw an error on mismatch.
 *
 * @param[in] dim      Object to compare against.
 * @param[in] function Function in which the error occurred.
 * @param[in] file     File in which the error occurred.
 * @param[in] line     Line in which the error occurred.
 */
template <typename T>
class compare_dimension
{
public:
    compare_dimension(const Dimensions<T> &dim, const char *function, const char *file, int line)
        : _dim{ dim }, _function{ function }, _file{ file }, _line{ line }
    {
    }

    /** Compare the given object against the stored one.
     *
     * @param[in] dim To be compared object.
     */
    arm_compute::Status operator()(const Dimensions<T> &dim)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
                                            "Objects have different dimensions");
        return arm_compute::Status{};
    }

private:
    const Dimensions<T> &_dim;
    const char *const    _function;
    const char *const    _file;
    const int            _line;
};

template <typename F>
inline arm_compute::Status for_each_error(F &&)
{
    return arm_compute::Status{};
}

template <typename F, typename T, typename... Ts>
inline arm_compute::Status for_each_error(F &&func, T &&arg, Ts &&... args)
{
    ARM_COMPUTE_RETURN_ON_ERROR(func(arg));
    ARM_COMPUTE_RETURN_ON_ERROR(for_each_error(func, args...));
    return arm_compute::Status{};
}

template <typename T>
struct get_tensor_info_t;
template <>
struct get_tensor_info_t<ITensorInfo *>
{
    ITensorInfo *operator()(const ITensor *tensor)
    {
        return tensor->info();
    }
};
} // namespace detail

/** Create an error if one of the pointers is a nullptr.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] pointers Pointers to check against nullptr.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
{
    const std::array<const void *, sizeof...(Ts)> pointers_array{ { std::forward<Ts>(pointers)... } };
    bool has_nullptr = std::any_of(pointers_array.begin(), pointers_array.end(), [&](const void *ptr)
    {
        return (ptr == nullptr);
    });
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed window is invalid.
 *
 * The subwindow is invalid if:
 * - It is not a valid window.
 * - Its dimensions don't match the full window's ones
 * - The step for each of its dimension is not identical to the corresponding one of the full window.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] full     Full size window
 * @param[in] win      Window to validate.
 *
 * @return Status
 */
arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line,
                                                 const Window &full, const Window &win);
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))

/** Return an error if the passed subwindow is invalid.
 *
 * The subwindow is invalid if:
 * - It is not a valid window.
 * - It is not fully contained inside the full window
 * - The step for each of its dimension is not identical to the corresponding one of the full window.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] full     Full size window
 * @param[in] sub      Sub-window to validate.
 *
 * @return Status
 */
arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line,
                                               const Window &full, const Window &sub);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBWINDOW(f, s) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))

/** Return an error if the window can't be collapsed at the given dimension.
 *
 * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] full     Full size window
 * @param[in] window   Window to be collapsed.
 * @param[in] dim      Dimension need to be checked.
 *
 * @return Status
 */
arm_compute::Status error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
                                                                 const Window &full, const Window &window, const int dim);
#define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))

/** Return an error if the passed coordinates have too many dimensions.
 *
 * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] pos      Coordinates to validate
 * @param[in] max_dim  Maximum number of dimensions allowed.
 *
 * @return Status
 */
arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
                                                        const Coordinates &pos, unsigned int max_dim);
#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
#define ARM_COMPUTE_RETURN_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))

/** Return an error if the passed window has too many dimensions.
 *
 * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] win      Window to validate
 * @param[in] max_dim  Maximum number of dimensions allowed.
 *
 * @return Status
 */
arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line,
                                                   const Window &win, unsigned int max_dim);
#define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))

/** Return an error if the passed dimension objects differ.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] dim1     The first object to be compared.
 * @param[in] dim2     The second object to be compared.
 * @param[in] dims     (Optional) Further allowed objects.
 *
 * @return Status
 */
template <typename T, typename... Ts>
arm_compute::Status error_on_mismatching_dimensions(const char *function, const char *file, int line,
                                                    const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
{
    ARM_COMPUTE_RETURN_ON_ERROR(detail::for_each_error(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed two tensor infos have different shapes from the given dimension
 *
 * @param[in] function      Function in which the error occurred.
 * @param[in] file          Name of the file where the error occurred.
 * @param[in] line          Line on which the error occurred.
 * @param[in] tensor_info_1 The first tensor info to be compared.
 * @param[in] tensor_info_2 The second tensor info to be compared.
 * @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                       const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    return error_on_mismatching_shapes(function, file, line, 0U, tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)...);
}
/** Return an error if the passed two tensors have different shapes from the given dimension
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor_1 The first tensor to be compared.
 * @param[in] tensor_2 The second tensor to be compared.
 * @param[in] tensors  (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                       const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
}
/** Return an error if the passed two tensors have different shapes from the given dimension
 *
 * @param[in] function      Function in which the error occurred.
 * @param[in] file          Name of the file where the error occurred.
 * @param[in] line          Line on which the error occurred.
 * @param[in] upper_dim     The dimension from which to check.
 * @param[in] tensor_info_1 The first tensor info to be compared.
 * @param[in] tensor_info_2 The second tensor info to be compared.
 * @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                       unsigned int upper_dim, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_1 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_2 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));

    const std::array < const ITensorInfo *, 2 + sizeof...(Ts) > tensors_info_array{ { tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_info_array.cbegin()), tensors_info_array.cend(), [&](const ITensorInfo * tensor_info)
    {
        return detail::have_different_dimensions((*tensors_info_array.cbegin())->tensor_shape(), tensor_info->tensor_shape(), upper_dim);
    }),
    function, file, line, "Tensors have different shapes");
    return arm_compute::Status{};
}
/** Return an error if the passed two tensors have different shapes from the given dimension
 *
 * @param[in] function  Function in which the error occurred.
 * @param[in] file      Name of the file where the error occurred.
 * @param[in] line      Line on which the error occurred.
 * @param[in] upper_dim The dimension from which to check.
 * @param[in] tensor_1  The first tensor to be compared.
 * @param[in] tensor_2  The second tensor to be compared.
 * @param[in] tensors   (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
                                                       unsigned int upper_dim, const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_1 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_2 == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(function, file, line, upper_dim, tensor_1->info(), tensor_2->info(),
                                                                           detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed two tensor infos have different data types
 *
 * @param[in] function     Function in which the error occurred.
 * @param[in] file         Name of the file where the error occurred.
 * @param[in] line         Line on which the error occurred.
 * @param[in] tensor_info  The first tensor info to be compared.
 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
                                                           const ITensorInfo *tensor_info, Ts... tensor_infos)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));

    DataType &&tensor_data_type = tensor_info->data_type();
    const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
    {
        return tensor_info_obj->data_type() != tensor_data_type;
    }),
    function, file, line, "Tensors have different data types");
    return arm_compute::Status{};
}
/** Return an error if the passed two tensors have different data types
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor   The first tensor to be compared.
 * @param[in] tensors  (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
                                                           const ITensor *tensor, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(function, file, line, tensor->info(),
                                                                               detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed tensor infos have different fixed point data types or different fixed point positions
 *
 * @note: If the first tensor doesn't have fixed point data type, the function returns without throwing an error
 *
 * @param[in] function      Function in which the error occurred.
 * @param[in] file          Name of the file where the error occurred.
 * @param[in] line          Line on which the error occurred.
 * @param[in] tensor_info_1 The first tensor info to be compared.
 * @param[in] tensor_info_2 The second tensor info to be compared.
 * @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_fixed_point(const char *function, const char *file, const int line,
                                                            const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    DataType &&first_data_type            = tensor_info_1->data_type();
    const int  first_fixed_point_position = tensor_info_1->fixed_point_position();

    if(!is_data_type_fixed_point(first_data_type))
    {
        return arm_compute::Status{};
    }

    const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->data_type() != first_data_type;
    }),
    function, file, line, "Tensors have different fixed point data types");
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->fixed_point_position() != first_fixed_point_position;
    }),
    function, file, line, "Tensors have different fixed point positions");

    return arm_compute::Status{};
}
/** Return an error if the passed tensor have different fixed point data types or different fixed point positions
 *
 * @note: If the first tensor doesn't have fixed point data type, the function returns without throwing an error
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor_1 The first tensor to be compared.
 * @param[in] tensor_2 The second tensor to be compared.
 * @param[in] tensors  (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_fixed_point(const char *function, const char *file, const int line,
                                                            const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point(function, file, line, tensor_1->info(), tensor_2->info(),
                                                                                detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_FIXED_POINT(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the passed tensor infos have different asymmetric quantized data types or different quantization info
 *
 * @note: If the first tensor info doesn't have asymmetric quantized data type, the function returns without throwing an error
 *
 * @param[in] function      Function in which the error occurred.
 * @param[in] file          Name of the file where the error occurred.
 * @param[in] line          Line on which the error occurred.
 * @param[in] tensor_info_1 The first tensor info to be compared.
 * @param[in] tensor_info_2 The second tensor info to be compared.
 * @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
                                                                  const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    DataType             &&first_data_type         = tensor_info_1->data_type();
    const QuantizationInfo first_quantization_info = tensor_info_1->quantization_info();

    if(!is_data_type_quantized_asymmetric(first_data_type))
    {
        return arm_compute::Status{};
    }

    const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->data_type() != first_data_type;
    }),
    function, file, line, "Tensors have different asymmetric quantized data types");
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->quantization_info() != first_quantization_info;
    }),
    function, file, line, "Tensors have different quantization information");

    return arm_compute::Status{};
}
/** Return an error if the passed tensor have different asymmetric quantized data types or different quantization info
 *
 * @note: If the first tensor doesn't have asymmetric quantized data type, the function returns without throwing an error
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor_1 The first tensor to be compared.
 * @param[in] tensor_2 The second tensor to be compared.
 * @param[in] tensors  (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
                                                                  const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(function, file, line, tensor_1->info(), tensor_2->info(),
                                                                                      detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] object   Tensor/multi-image to validate.
 * @param[in] format   First format allowed.
 * @param[in] formats  (Optional) Further allowed formats.
 */
template <typename T, typename F, typename... Fs>
void error_on_format_not_in(const char *function, const char *file, const int line,
                            const T *object, F &&format, Fs &&... formats)
{
    ARM_COMPUTE_ERROR_ON_LOC(object == nullptr, function, file, line);

    Format &&object_format = object->info()->format();
    ARM_COMPUTE_UNUSED(object_format);

    ARM_COMPUTE_ERROR_ON_LOC(object_format == Format::UNKNOWN, function, file, line);

    const std::array<F, sizeof...(Fs)> formats_array{ { std::forward<Fs>(formats)... } };
    ARM_COMPUTE_UNUSED(formats_array);

    ARM_COMPUTE_ERROR_ON_LOC_MSG(object_format != format && std::none_of(formats_array.begin(), formats_array.end(), [&](const F & f)
    {
        return f == object_format;
    }),
    function, file, line, "Format %s not supported by this kernel", string_from_format(object_format).c_str());
}
#define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)

/** Return an error if the data type of the passed tensor info does not match any of the data types provided.
 *
 * @param[in] function    Function in which the error occurred.
 * @param[in] file        Name of the file where the error occurred.
 * @param[in] line        Line on which the error occurred.
 * @param[in] tensor_info Tensor info to validate.
 * @param[in] dt          First data type allowed.
 * @param[in] dts         (Optional) Further allowed data types.
 *
 * @return Status
 */
template <typename T, typename... Ts>
inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
                                                     const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);

    const DataType &tensor_dt = tensor_info->data_type(); //NOLINT
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);

    const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(tensor_dt != dt && std::none_of(dts_array.begin(), dts_array.end(), [&](const T & d)
    {
        return d == tensor_dt;
    }),
    function, file, line, "ITensor data type %s not supported by this kernel", string_from_data_type(tensor_dt).c_str());
    return arm_compute::Status{};
}
/** Return an error if the data type of the passed tensor does not match any of the data types provided.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor   Tensor to validate.
 * @param[in] dt       First data type allowed.
 * @param[in] dts      (Optional) Further allowed data types.
 *
 * @return Status
 */
template <typename T, typename... Ts>
inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
                                                     const ITensor *tensor, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor->info(), std::forward<T>(dt), std::forward<Ts>(dts)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))

/** Return an error if the data type or the number of channels of the passed tensor info does not match any of the data types and number of channels provided.
 *
 * @param[in] function     Function in which the error occurred.
 * @param[in] file         Name of the file where the error occurred.
 * @param[in] line         Line on which the error occurred.
 * @param[in] tensor_info  Tensor info to validate.
 * @param[in] num_channels Number of channels to check
 * @param[in] dt           First data type allowed.
 * @param[in] dts          (Optional) Further allowed data types.
 *
 * @return Status
 */
template <typename T, typename... Ts>
inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
                                                             const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor_info, std::forward<T>(dt), std::forward<Ts>(dts)...));
    const size_t tensor_nc = tensor_info->num_channels();
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(tensor_nc != num_channels, function, file, line, "Number of channels %d. Required number of channels %d", tensor_nc, num_channels);
    return arm_compute::Status{};
}
/** Return an error if the data type or the number of channels of the passed tensor does not match any of the data types and number of channels provided.
 *
 * @param[in] function     Function in which the error occurred.
 * @param[in] file         Name of the file where the error occurred.
 * @param[in] line         Line on which the error occurred.
 * @param[in] tensor       Tensor to validate.
 * @param[in] num_channels Number of channels to check
 * @param[in] dt           First data type allowed.
 * @param[in] dts          (Optional) Further allowed data types.
 *
 * @return Status
 */
template <typename T, typename... Ts>
inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
                                                             const ITensor *tensor, size_t num_channels, T &&dt, Ts &&... dts)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(error_on_data_type_channel_not_in(function, file, line, tensor->info(), num_channels, std::forward<T>(dt), std::forward<Ts>(dts)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))

/** Return an error if the tensor is not 2D.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor   Tensor to validate.
 *
 * @return Status
 */
arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
                                           const ITensor *tensor);
#define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
#define ARM_COMPUTE_RETURN_ERROR_ON_TENSOR_NOT_2D(t) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))

/** Return an error if the channel is not in channels.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] cn       Input channel
 * @param[in] channel  First channel allowed.
 * @param[in] channels (Optional) Further allowed channels.
 *
 * @return Status
 */
template <typename T, typename... Ts>
inline arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line,
                                                   T cn, T &&channel, Ts &&... channels)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);

    const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(channel != cn && std::none_of(channels_array.begin(), channels_array.end(), [&](const T & f)
    {
        return f == cn;
    }),
    function, file, line);
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))

/** Return an error if the channel is not in format.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] fmt      Input channel
 * @param[in] cn       First channel allowed.
 *
 * @return Status
 */
arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
                                                         Format fmt, Channel cn);
#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))

/** Return an error if the @ref IMultiHOG container is invalid
 *
 * An @ref IMultiHOG container is invalid if:
 *
 * -# it is a nullptr
 * -# it doesn't contain models
 * -# it doesn't have the HOG data objects with the same phase_type, normalization_type and l2_hyst_threshold (if normalization_type == L2HYS_NORM)
 *
 * @param[in] function  Function in which the error occurred.
 * @param[in] file      Name of the file where the error occurred.
 * @param[in] line      Line on which the error occurred.
 * @param[in] multi_hog IMultiHOG container to validate
 *
 * @return Status
 */
arm_compute::Status error_on_invalid_multi_hog(const char *function, const char *file, const int line,
                                               const IMultiHOG *multi_hog);
#define ARM_COMPUTE_ERROR_ON_INVALID_MULTI_HOG(m) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_MULTI_HOG(m) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))

/** Return an error if the kernel is not configured.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] kernel   Kernel to validate.
 */
arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line,
                                                 const IKernel *kernel);
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
#define ARM_COMPUTE_RETURN_ERROR_ON_UNCONFIGURED_KERNEL(k) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))

/** Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
 *
 * @param[in] function     Function in which the error occurred.
 * @param[in] file         Name of the file where the error occurred.
 * @param[in] line         Line on which the error occurred.
 * @param[in] parent_shape Parent tensor shape
 * @param[in] coords       Coordinates inside the parent tensor where the first element of the subtensor is
 * @param[in] shape        Shape of the subtensor
 *
 * @return Status
 */
arm_compute::Status error_on_invalid_subtensor(const char *function, const char *file, const int line,
                                               const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))

/** Return an error if the valid region of a subtensor is not inside the valid region of the parent tensor.
 *
 * @param[in] function            Function in which the error occurred.
 * @param[in] file                Name of the file where the error occurred.
 * @param[in] line                Line on which the error occurred.
 * @param[in] parent_valid_region Parent valid region.
 * @param[in] valid_region        Valid region of subtensor.
 *
 * @return Status
 */
arm_compute::Status error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
                                                            const ValidRegion &parent_valid_region, const ValidRegion &valid_region);
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))

/** Return an error if the input fixed-point positions are different.
 *
 * @param[in] function      Function in which the error occurred.
 * @param[in] file          Name of the file where the error occurred.
 * @param[in] line          Line on which the error occurred.
 * @param[in] tensor_info_1 The first tensor info to be compared.
 * @param[in] tensor_info_2 The second tensor info to be compared.
 * @param[in] tensor_infos  (Optional) Further allowed tensor infos.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_fixed_point_position(const char *function, const char *file, const int line,
                                                                     const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
{
    const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_info_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_info_array.begin(), tensor_info_array.end(), [&](const ITensorInfo * tensor_info)
    {
        return tensor_info->fixed_point_position() != tensor_info_1->fixed_point_position();
    }),
    function, file, line, "Tensors have different fixed-point positions");
    return arm_compute::Status{};
}
/** Return an error if the input fixed-point positions are different.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] tensor_1 The first tensor to be compared.
 * @param[in] tensor_2 The second tensor to be compared.
 * @param[in] tensors  (Optional) Further allowed tensors.
 *
 * @return Status
 */
template <typename... Ts>
inline arm_compute::Status error_on_mismatching_fixed_point_position(const char *function, const char *file, const int line,
                                                                     const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
{
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point_position(function, file, line, tensor_1->info(), tensor_2->info(),
                                                                                         detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT_POSITION(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_fixed_point_position(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_FIXED_POINT_POSITION(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_fixed_point_position(__func__, __FILE__, __LINE__, __VA_ARGS__))

/** Return an error if the fixed-point value is not representable in the specified Q format.
 *
 * @param[in] function    Function in which the error occurred.
 * @param[in] file        Name of the file where the error occurred.
 * @param[in] line        Line on which the error occurred.
 * @param[in] value       The floating point value to be checked.
 * @param[in] tensor_info Input tensor info that has information on data type and fixed-point position.
 *
 * @return Status
 */
inline arm_compute::Status error_on_value_not_representable_in_fixed_point(const char *function, const char *file, int line,
                                                                           float value, const ITensorInfo *tensor_info)
{
    const int          fixed_point_position = tensor_info->fixed_point_position();
    const DataType     dt                   = tensor_info->data_type();
    const unsigned int q_max_range          = 0xFFFFFFFFu >> (((sizeof(unsigned int) - element_size_from_data_type(dt)) * 8) + 1);
    const float        max_range            = q_max_range / (static_cast<float>(1 << fixed_point_position));

    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(value > max_range, function, file, line,
                                        "Value %f is not representable in %s with fixed-point position %d", value, string_from_data_type(dt).c_str(), fixed_point_position);
    return arm_compute::Status{};
}
/** Return an error an error if the fixed-point value is not representable in the specified Q format.
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] value    The floating point value to be checked.
 * @param[in] tensor   Input tensor that has information on data type and fixed-point position.
 *
 * @return Status
 */
inline arm_compute::Status error_on_value_not_representable_in_fixed_point(const char *function, const char *file, int line,
                                                                           float value, const ITensor *tensor)
{
    ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_value_not_representable_in_fixed_point(function, file, line, value, tensor->info()));
    return arm_compute::Status{};
}
#define ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(...) \
    ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_value_not_representable_in_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
#define ARM_COMPUTE_RETURN_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(...) \
    ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_value_not_representable_in_fixed_point(__func__, __FILE__, __LINE__, __VA_ARGS__))
}
#endif /* __ARM_COMPUTE_VALIDATE_H__*/
