/*
 * 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.
 */
#include "arm_compute/core/Validate.h"

void arm_compute::error_on_mismatching_windows(const char *function, const char *file, const int line,
                                               const arm_compute::Window &full, const arm_compute::Window &win)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);

    full.validate();
    win.validate();

    for(size_t i = 0; i < arm_compute::Coordinates::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC(full[i].start() != win[i].start(), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC(full[i].end() != win[i].end(), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC(full[i].step() != win[i].step(), function, file, line);
    }
}

void arm_compute::error_on_invalid_subwindow(const char *function, const char *file, const int line,
                                             const arm_compute::Window &full, const arm_compute::Window &sub)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);

    full.validate();
    sub.validate();

    for(size_t i = 0; i < arm_compute::Coordinates::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC(full[i].start() > sub[i].start(), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC(full[i].end() < sub[i].end(), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC(full[i].step() != sub[i].step(), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC((sub[i].start() - full[i].start()) % sub[i].step(), function, file, line);
    }
}

void arm_compute::error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
                                                               const arm_compute::Window &full, const arm_compute::Window &window, const int dim)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(dim);

    full.validate();
    window.validate();

    ARM_COMPUTE_ERROR_ON_LOC(window[dim].start() != 0, function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC(window[dim].start() != full[dim].start(), function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC(full[dim].end() != window[dim].end(), function, file, line);
}

void arm_compute::error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
                                                      const arm_compute::Coordinates &pos, unsigned int max_dim)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(pos);

    for(unsigned int i = max_dim; i < arm_compute::Coordinates::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC(pos[i] != 0, function, file, line);
    }
}

void arm_compute::error_on_window_dimensions_gte(const char *function, const char *file, const int line,
                                                 const arm_compute::Window &win, unsigned int max_dim)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(win);

    for(unsigned int i = max_dim; i < arm_compute::Coordinates::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC_MSG(win[i].start() != 0 || win[i].end() != win[i].step(),
                                     function, file, line,
                                     "Maximum number of dimensions expected %u but dimension %u is not empty", max_dim, i);
    }
}

void arm_compute::error_on_tensor_not_2d(const char *function, const char *file, const int line,
                                         const arm_compute::ITensor *tensor)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(tensor);

    ARM_COMPUTE_ERROR_ON_LOC(tensor == nullptr, function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC_MSG(tensor->info()->num_dimensions() != 2,
                                 function, file, line,
                                 "Only 2D Tensors are supported by this kernel (%d passed)", tensor->info()->num_dimensions());
}

void arm_compute::error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
                                                       arm_compute::Format fmt, arm_compute::Channel cn)
{
    ARM_COMPUTE_ERROR_ON_LOC(fmt == arm_compute::Format::UNKNOWN, function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC(cn == arm_compute::Channel::UNKNOWN, function, file, line);

    switch(fmt)
    {
        case arm_compute::Format::RGB888:
            arm_compute::error_on_channel_not_in(function, file, line, cn, arm_compute::Channel::R, arm_compute::Channel::G, arm_compute::Channel::B);
            break;
        case arm_compute::Format::RGBA8888:
            arm_compute::error_on_channel_not_in(function, file, line, cn, arm_compute::Channel::R, arm_compute::Channel::G, arm_compute::Channel::B, arm_compute::Channel::A);
            break;
        case arm_compute::Format::UV88:
            arm_compute::error_on_channel_not_in(function, file, line, cn, arm_compute::Channel::U, arm_compute::Channel::V);
            break;
        case arm_compute::Format::IYUV:
        case arm_compute::Format::UYVY422:
        case arm_compute::Format::YUYV422:
        case arm_compute::Format::NV12:
        case arm_compute::Format::NV21:
        case arm_compute::Format::YUV444:
            arm_compute::error_on_channel_not_in(function, file, line, cn, arm_compute::Channel::Y, arm_compute::Channel::U, arm_compute::Channel::V);
            break;
        default:
            ARM_COMPUTE_ERROR_LOC(function, file, line, "Not supported format.");
    }
}

void arm_compute::error_on_invalid_multi_hog(const char *function, const char *file, const int line,
                                             const arm_compute::IMultiHOG *multi_hog)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);

    ARM_COMPUTE_ERROR_ON_LOC(nullptr == multi_hog, function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC(0 == multi_hog->num_models(), function, file, line);

    for(size_t i = 1; i < multi_hog->num_models(); ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC_MSG(multi_hog->model(0)->info()->phase_type() != multi_hog->model(i)->info()->phase_type(),
                                     function, file, line,
                                     "All HOG parameters must have the same phase type");
        ARM_COMPUTE_ERROR_ON_LOC_MSG(multi_hog->model(0)->info()->normalization_type() != multi_hog->model(i)->info()->normalization_type(),
                                     function, file, line,
                                     "All HOG parameters must have the same normalization type");
        ARM_COMPUTE_ERROR_ON_LOC_MSG((multi_hog->model(0)->info()->l2_hyst_threshold() != multi_hog->model(i)->info()->l2_hyst_threshold())
                                     && (multi_hog->model(0)->info()->normalization_type() == arm_compute::HOGNormType::L2HYS_NORM),
                                     function, file, line,
                                     "All HOG parameters must have the same l2 hysteresis threshold if you use L2 hysteresis normalization type");
    }
}

void arm_compute::error_on_unconfigured_kernel(const char *function, const char *file, const int line,
                                               const arm_compute::IKernel *kernel)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(kernel);

    ARM_COMPUTE_ERROR_ON_LOC(kernel == nullptr, function, file, line);
    ARM_COMPUTE_ERROR_ON_LOC_MSG((kernel->window().x().start() == kernel->window().x().end()) && (kernel->window().x().end() == 0) && (kernel->window().x().step() == 0),
                                 function, file, line,
                                 "This kernel hasn't been configured.");
}

void arm_compute::error_on_invalid_subtensor(const char *function, const char *file, const int line,
                                             const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(parent_shape);
    ARM_COMPUTE_UNUSED(coords);
    ARM_COMPUTE_UNUSED(shape);

    // Subtensor should not index in x, y dimensions.
    ARM_COMPUTE_ERROR_ON_LOC(((coords.x() != 0) && (coords.y() != 0)), function, file, line);
    // Subtensor shape should match parent tensor in x, y dimensions.
    ARM_COMPUTE_ERROR_ON_LOC(((parent_shape.x() != shape.x()) && (parent_shape.y() != parent_shape.y())), function, file, line);

    // Check dimensions
    for(unsigned int i = 0; i < TensorShape::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON_LOC(((coords[i] >= static_cast<int>(parent_shape[i])) || (coords[i] + static_cast<int>(shape[i]) > static_cast<int>(parent_shape[i]))),
                                 function, file, line);
    }
}

void arm_compute::error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
                                                          const ValidRegion &parent_valid_region, const ValidRegion &valid_region)
{
    ARM_COMPUTE_UNUSED(function);
    ARM_COMPUTE_UNUSED(file);
    ARM_COMPUTE_UNUSED(line);
    ARM_COMPUTE_UNUSED(parent_valid_region);
    ARM_COMPUTE_UNUSED(valid_region);

    // Check valid regions
    for(unsigned int d = 0; d < TensorShape::num_max_dimensions; ++d)
    {
        ARM_COMPUTE_ERROR_ON_LOC((parent_valid_region.anchor[d] > valid_region.anchor[d]), function, file, line);
        ARM_COMPUTE_ERROR_ON_LOC((parent_valid_region.anchor[d] + static_cast<int>(parent_valid_region.shape[d])) < (valid_region.anchor[d] + static_cast<int>(valid_region.shape[d])),
                                 function, file, line);
    }
}
