/*
 * 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 "arm_compute/core/NEON/kernels/NECropKernel.h"

#include "arm_compute/core/CPP/Validate.h"
#include "arm_compute/core/IAccessWindow.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Window.h"

#include "arm_compute/core/NEON/wrapper/wrapper.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/helpers/bit_ops.h"
#include "arm_compute/core/utils/helpers/tensor_transform.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.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
