/*
 * Copyright (c) 2019-2020 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 "src/core/NEON/kernels/NECropKernel.h"

#include "arm_compute/core/IAccessWindow.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Window.h"
#include "arm_compute/core/utils/helpers/tensor_transform.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "src/core/CPP/Validate.h"
#include "src/core/NEON/wrapper/wrapper.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"
#include "src/core/utils/helpers/bit_ops.h"

namespace arm_compute
{
namespace
{
template <typename T>
inline float32x4_t load_as_f32(T *ptr)
{
    ARM_COMPUTE_UNUSED(ptr);
    ARM_COMPUTE_ERROR("Type not supported.");
}

template <>
inline float32x4_t load_as_f32(float *ptr)
{
    return wrapper::vloadq(ptr);
}

template <>
inline float32x4_t load_as_f32(int32_t *ptr)
{
    return vcvtq_f32_s32(wrapper::vloadq(ptr));
}

template <>
inline float32x4_t load_as_f32(uint32_t *ptr)
{
    return vcvtq_f32_u32(wrapper::vloadq(ptr));
}

template <>
inline float32x4_t load_as_f32(int16_t *ptr)
{
    return vcvtq_f32_s32(vmovl_s16(wrapper::vload(ptr)));
}

template <>
inline float32x4_t load_as_f32(uint16_t *ptr)
{
    return vcvtq_f32_u32(vmovl_u16(wrapper::vload(ptr)));
}

template <>
inline float32x4_t load_as_f32(uint8_t *ptr)
{
    return vcvtq_f32_u32(vmovl_u16(vget_low_u16(vmovl_u8(wrapper::vload(ptr)))));
}

#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
template <>
inline float32x4_t load_as_f32(float16_t *ptr)
{
    return vcvt_f32_f16(wrapper::vload(ptr));
}
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */

template <typename T>
inline void in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset,
                                  int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
{
    // Reverse elements if width flipped.
    if(is_width_flipped)
    {
        // Collapse first dimension if possible.
        if(input_has_single_channel)
        {
            int32_t     x = output_width_start;
            Coordinates negative_offset(input_offset);
            negative_offset.set(1, negative_offset[1] - window_step_x + 1);
            for(; x <= output_width_limit - window_step_x; x += window_step_x, negative_offset[1] -= window_step_x)
            {
                auto in = load_as_f32(reinterpret_cast<T *>(input->ptr_to_element(negative_offset)));

                in = wrapper::vrev64(in);
                in = wrapper::vcombine(wrapper::vgethigh(in), wrapper::vgetlow(in));

                wrapper::vstore(output_ptr + x, in);
            }
            input_offset[1] = negative_offset[1] + window_step_x - 1;
            for(; x < output_width_limit; ++x, --input_offset[1])
            {
                *(output_ptr + x) = static_cast<float>(*reinterpret_cast<T *>(input->ptr_to_element(input_offset)));
            }
        }
        else
        {
            for(int32_t x = output_width_start; x < output_width_limit; ++x, --input_offset[1])
            {
                input_offset.set(0, 0);
                int32_t c = 0;
                for(; c <= static_cast<int32_t>(input->info()->dimension(0)) - window_step_x; c += window_step_x, input_offset[0] += window_step_x)
                {
                    auto in = load_as_f32(reinterpret_cast<T *>(input->ptr_to_element(input_offset)));
                    wrapper::vstore(output_ptr + x * output->info()->dimension(0) + c, in);
                }
                for(; c < static_cast<int32_t>(input->info()->dimension(0)); ++c, ++input_offset[0])
                {
                    *(output_ptr + x * output->info()->dimension(0) + c) = static_cast<float>(*reinterpret_cast<T *>(input->ptr_to_element(input_offset)));
                }
            }
        }
    }
    else
    {
        // Use memcpy if the elements don't need converting to float.
        if(std::is_same<T, float>::value)
        {
            memcpy(static_cast<void *>(output_ptr + output_width_start * output->info()->dimension(0)),
                   reinterpret_cast<const void *>(input->ptr_to_element(input_offset)),
                   (output_width_limit - output_width_start) * output->info()->dimension(0) * output->info()->element_size());
        }
        else
        {
            int32_t x                = 0;
            int32_t limit            = (output_width_limit - output_width_start) * static_cast<int32_t>(output->info()->dimension(0));
            float *output_start_ptr = output_ptr + output_width_start * output->info()->dimension(0);
            for(; x <= limit - window_step_x; x += window_step_x, input_offset[0] += window_step_x)
            {
                auto in = load_as_f32(reinterpret_cast<T *>(input->ptr_to_element(input_offset)));
                wrapper::vstore(output_start_ptr + x, in);
            }
            for(; x < limit; ++x, ++input_offset[0])
            {
                *(output_start_ptr + x) = static_cast<float>(*reinterpret_cast<T *>(input->ptr_to_element(input_offset)));
            }
        }
    }
}

inline void out_of_bounds_crop_window(const ITensor *output, float *output_ptr, float extrapolation_value,
                                      int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit)
{
    auto    in               = wrapper::vdup_n(extrapolation_value, wrapper::traits::vector_128_tag());
    int32_t x                = 0;
    int32_t limit            = (output_width_limit - output_width_start) * static_cast<int32_t>(output->info()->dimension(0));
    float *output_start_ptr = output_ptr + output_width_start * output->info()->dimension(0);
    for(; x <= limit - window_step_x; x += window_step_x)
    {
        wrapper::vstore(output_start_ptr + x, in);
    }
    for(; x < limit; ++x)
    {
        *(output_start_ptr + x) = extrapolation_value;
    }
}

inline void execute_window(const ITensor *input, const ITensor *output, Coordinates input_offset, float extrapolation_value,
                           const std::array<uint32_t, 2> &rows_out_of_bounds, const std::array<uint32_t, 2> &cols_out_of_bounds, NECropKernel::InBoundsCropFunction *in_bounds_crop_function,
                           bool is_height_flipped, bool has_cols_in_bounds, bool has_cols_out_of_bounds_before, bool has_cols_out_of_bounds_after, bool input_has_single_channel, bool is_width_flipped)
{
    // Output is always float.
    const int window_step_x = 16 / sizeof(float);
    auto     *output_ptr    = reinterpret_cast<float *>(output->buffer());
    //  Output window:
    //  --------------------------------
    //  |          Out of bounds       |
    //  |          rows before         |
    //  |------------------------------|
    //  | Out of | In         | Out of |
    //  | bounds | bounds     | bounds |
    //  | cols   | elements   | cols   |
    //  | before | copied     | after  |
    //  |        | from input |        |
    //  --------------------------------
    //  |        Out of bounds         |
    //  |        rows after            |
    //  |------------------------------|
    // Fill all output rows that have no elements that are within the input bounds with the extrapolation value.
    // First for the rows before the in bounds rows.
    out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0, rows_out_of_bounds[0] * output->info()->dimension(1));
    output_ptr += rows_out_of_bounds[0] * output->info()->dimension(1) * output->info()->dimension(0);
    // Iterate through each row that has any elements within the input bounds.
    for(uint32_t row = rows_out_of_bounds[0]; static_cast<int32_t>(row) < static_cast<int32_t>(output->info()->dimension(2) - rows_out_of_bounds[1]);
        ++row, is_height_flipped ? --input_offset[2] : ++input_offset[2])
    {
        // Fill all elements in the row that are out of bounds with the extrapolation value.
        // First for the elements before the in bounds elements.
        if(has_cols_out_of_bounds_before)
        {
            out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0, cols_out_of_bounds[0]);
        }
        // Copy all elements within the input bounds from the input tensor.
        if(has_cols_in_bounds)
        {
            (*in_bounds_crop_function)(input, output, output_ptr, input_offset, window_step_x, cols_out_of_bounds[0],
                                       output->info()->dimension(1) - cols_out_of_bounds[1], input_has_single_channel, is_width_flipped);
        }
        // Fill all elements after the in bounds elements with the extrapolation value.
        if(has_cols_out_of_bounds_after)
        {
            out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, output->info()->dimension(1) - cols_out_of_bounds[1], output->info()->dimension(1));
        }
        output_ptr += output->info()->dimension(1) * output->info()->dimension(0);
    }
    // Fill all rows after the in bounds elements with the extrapolation value.
    out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0, rows_out_of_bounds[1] * output->info()->dimension(1));
}
} // namespace

NECropKernel::NECropKernel()
    : _input(nullptr), _crop_boxes(nullptr), _box_ind(nullptr), _output(nullptr), _start(), _end(), _crop_box_ind(0), _extrapolation_value(0), _rows_out_of_bounds(), _cols_out_of_bounds(),
      _in_bounds_crop_function(nullptr)
{
}

void NECropKernel::configure(const ITensor *input, const ITensor *crop_boxes, const ITensor *box_ind, ITensor *output, uint32_t crop_box_ind, float extrapolation_value)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
    ARM_COMPUTE_ERROR_THROW_ON(validate(input->info(), crop_boxes->info(), box_ind->info(), output->info(), crop_box_ind, extrapolation_value));

    _input               = input;
    _crop_boxes          = crop_boxes;
    _box_ind             = box_ind;
    _output              = output;
    _crop_box_ind        = crop_box_ind;
    _extrapolation_value = extrapolation_value;

    switch(input->info()->data_type())
    {
        case DataType::F32:
            _in_bounds_crop_function = &in_bounds_crop_window<float>;
            break;
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
        case DataType::F16:
            _in_bounds_crop_function = &in_bounds_crop_window<float16_t>;
            break;
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
        case DataType::U32:
            _in_bounds_crop_function = &in_bounds_crop_window<uint32_t>;
            break;
        case DataType::S32:
            _in_bounds_crop_function = &in_bounds_crop_window<int32_t>;
            break;
        case DataType::U16:
            _in_bounds_crop_function = &in_bounds_crop_window<uint16_t>;
            break;
        case DataType::S16:
            _in_bounds_crop_function = &in_bounds_crop_window<int16_t>;
            break;
        case DataType::U8:
            _in_bounds_crop_function = &in_bounds_crop_window<uint8_t>;
            break;
        default:
            ARM_COMPUTE_ERROR("Datatype not supported");
    }
}

Status NECropKernel::validate(const ITensorInfo *input, const ITensorInfo *crop_boxes, const ITensorInfo *box_ind, const ITensorInfo *output, uint32_t crop_box_ind, float extrapolation_value)
{
    ARM_COMPUTE_UNUSED(extrapolation_value);
    ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8, DataType::U16, DataType::S16, DataType::F16, DataType::U32, DataType::S32, DataType::F32);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(input, DataLayout::NHWC);
    ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape().num_dimensions() > 4);
    ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[0] != 4);
    ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[1] != box_ind->tensor_shape()[0]);
    ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[1] <= crop_box_ind);
    ARM_COMPUTE_RETURN_ERROR_ON(box_ind->tensor_shape()[0] <= crop_box_ind);
    if(output->total_size() > 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(output, DataType::F32);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, output);
        ARM_COMPUTE_RETURN_ERROR_ON(output->num_dimensions() != 3);
        ARM_COMPUTE_RETURN_ERROR_ON(output->has_padding());
    }
    return Status{};
}

void NECropKernel::configure_output_shape()
{
    // _crop_box_ind is used to index _crop_boxes and retrieve the appropriate crop box.
    // The crop box is specified by normalized coordinates [y0, x0, y1, x1].
    const float x0 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(1, _crop_box_ind)));
    const float y0 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(0, _crop_box_ind)));
    const float x1 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(3, _crop_box_ind)));
    const float y1 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(2, _crop_box_ind)));
    // The normalized coordiantes are scaled to retrieve the floating point image coordinates which are rounded to integers.
    _start = Coordinates(std::floor(x0 * (_input->info()->tensor_shape()[1] - 1) + 0.5f),
                         std::floor(y0 * (_input->info()->tensor_shape()[2] - 1) + 0.5f));
    _end = Coordinates(std::floor(x1 * (_input->info()->tensor_shape()[1] - 1) + 0.5f),
                       std::floor(y1 * (_input->info()->tensor_shape()[2] - 1) + 0.5f));
    const TensorShape out_shape(_input->info()->tensor_shape()[0], abs(_end[0] - _start[0]) + 1, abs(_end[1] - _start[1]) + 1);
    _output->info()->set_tensor_shape(out_shape);

    bool is_width_flipped  = _end[0] < _start[0];
    bool is_height_flipped = _end[1] < _start[1];
    if(is_height_flipped)
    {
        _rows_out_of_bounds[0] = _start[1] >= static_cast<int32_t>(_input->info()->dimension(2)) ? std::min(static_cast<uint32_t>(_start[1] - _input->info()->dimension(2) + 1),
                                                                                                            static_cast<uint32_t>(_output->info()->dimension(2))) :
                                 0;
        _rows_out_of_bounds[1] = _end[1] < 0 ? std::min(static_cast<uint32_t>(-_end[1]),
                                                        static_cast<uint32_t>(_output->info()->dimension(2))) :
                                 0;
    }
    else
    {
        _rows_out_of_bounds[0] = _start[1] < 0 ? std::min(static_cast<uint32_t>(-_start[1]),
                                                          static_cast<uint32_t>(_output->info()->dimension(2))) :
                                 0;
        _rows_out_of_bounds[1] = _end[1] >= static_cast<int32_t>(_input->info()->dimension(2)) ? std::min(static_cast<uint32_t>(_end[1] - _input->info()->dimension(2) + 1),
                                                                                                          static_cast<uint32_t>(_output->info()->dimension(2))) :
                                 0;
    }
    if(is_width_flipped)
    {
        _cols_out_of_bounds[0] = _start[0] >= static_cast<int32_t>(_input->info()->dimension(1)) ? std::min(static_cast<uint32_t>(_start[0] - _input->info()->dimension(1) + 1),
                                                                                                            static_cast<uint32_t>(_output->info()->dimension(1))) :
                                 0;
        _cols_out_of_bounds[1] = _end[0] < 0 ? std::min(static_cast<uint32_t>(-_end[0]),
                                                        static_cast<uint32_t>(_output->info()->dimension(1))) :
                                 0;
    }
    else
    {
        _cols_out_of_bounds[0] = _start[0] < 0 ? std::min(static_cast<uint32_t>(-_start[0]),
                                                          static_cast<uint32_t>(_output->info()->dimension(1))) :
                                 0;
        _cols_out_of_bounds[1] = _end[0] >= static_cast<int32_t>(_input->info()->dimension(1)) ? std::min(static_cast<uint32_t>(_end[0] - _input->info()->dimension(1) + 1),
                                                                                                          static_cast<uint32_t>(_output->info()->dimension(1))) :
                                 0;
    }

    INEKernel::configure(calculate_max_window(*_output->info()));
}

void NECropKernel::run(const Window &window, const ThreadInfo &info)
{
    ARM_COMPUTE_UNUSED(window, info);
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);

    ARM_COMPUTE_ERROR_ON(_input->info()->has_padding());
    ARM_COMPUTE_ERROR_ON(_output->info()->has_padding());

    uint32_t    batch_index = *(reinterpret_cast<int32_t *>(_box_ind->ptr_to_element(Coordinates(_crop_box_ind))));
    Coordinates input_offset(0, _end[0] < _start[0] ? _start[0] - _cols_out_of_bounds[0] : _start[0] + _cols_out_of_bounds[0],
                             _end[1] < _start[1] ? _start[1] - _rows_out_of_bounds[0] : _start[1] + _rows_out_of_bounds[0], batch_index);
    execute_window(_input, _output, input_offset, _extrapolation_value, _rows_out_of_bounds, _cols_out_of_bounds, _in_bounds_crop_function, _end[1] < _start[1],
                   _cols_out_of_bounds[0] + _cols_out_of_bounds[1] < _output->info()->dimension(1), _cols_out_of_bounds[0] > 0, _cols_out_of_bounds[1] > 0,
                   _start[0] <= _end[0], _end[0] < _start[0]);
}
} // namespace arm_compute
