/*
 * Copyright (c) 2018-2020, 2024 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/utils/helpers/tensor_transform.h"

#include "bit_ops.h"

namespace arm_compute
{
namespace helpers
{
namespace tensor_transform
{
int calculate_stride_on_index(int index, Coordinates strides)
{
    return index >= static_cast<int>(strides.num_dimensions()) ? 1 : strides[index];
}

int calculate_start_on_index(
    TensorShape input_shape, int index, Coordinates starts, Coordinates strides, int32_t begin_mask)
{
    // Early exit
    if (index >= static_cast<int>(starts.num_dimensions()))
    {
        return 0;
    }

    // Get stride
    const int stride = calculate_stride_on_index(index, strides);

    // Calculate start
    int start = starts[index];

    // Reset in case of begin mask present
    if (arm_compute::helpers::bit_ops::is_bit_set(begin_mask, index))
    {
        start = stride > 0 ? std::numeric_limits<int>::lowest() : std::numeric_limits<int>::max();
    }

    // Account negative start points
    const int dim_size = input_shape[index];
    if (start < 0)
    {
        start += dim_size;
    }

    // Final clamp
    start = utility::clamp(start, 0, dim_size - 1);

    return start;
}

int calculate_end_on_index(TensorShape input_shape,
                           int         index,
                           int         start_on_index,
                           Coordinates ends,
                           Coordinates strides,
                           int32_t     end_mask,
                           int32_t     shrink_axis_mask)
{
    // Early exit
    if (index >= static_cast<int>(ends.num_dimensions()))
    {
        return input_shape[index];
    }

    const int  stride      = calculate_stride_on_index(index, strides);
    const bool shrink_axis = arm_compute::helpers::bit_ops::is_bit_set(shrink_axis_mask, index);

    // Calculate start
    int stop = ends[index];

    // Shrink dimension
    if (shrink_axis)
    {
        if (start_on_index == std::numeric_limits<int>::max())
        {
            stop = start_on_index;
        }
        else
        {
            stop = start_on_index + 1;
        }
    }

    // Reset in case of begin mask present
    if (arm_compute::helpers::bit_ops::is_bit_set(end_mask, index) && !shrink_axis)
    {
        stop = (stride > 0) ? std::numeric_limits<int>::max() : std::numeric_limits<int>::lowest();
    }

    // Account negative end points
    const int dim_size = input_shape[index];
    if (stop < 0)
    {
        stop += dim_size;
    }

    // Final clamp
    if (stride > 0)
        stop = utility::clamp(stop, 0, dim_size);
    else
        stop = utility::clamp(stop, -1, dim_size - 1);

    return stop;
}

std::tuple<Coordinates, Coordinates, Coordinates> calculate_strided_slice_coords(TensorShape input_shape,
                                                                                 Coordinates starts,
                                                                                 Coordinates ends,
                                                                                 Coordinates strides,
                                                                                 int32_t     begin_mask,
                                                                                 int32_t     end_mask,
                                                                                 int32_t     shrink_axis_mask)
{
    Coordinates starts_abs{};
    Coordinates ends_abs{};
    Coordinates final_strides{};

    for (unsigned int i = 0; i < input_shape.num_dimensions(); ++i)
    {
        const int start_i = calculate_start_on_index(input_shape, i, starts, strides, begin_mask);
        starts_abs.set(i, start_i);
        ends_abs.set(i, calculate_end_on_index(input_shape, i, start_i, ends, strides, end_mask, shrink_axis_mask));
        final_strides.set(i, calculate_stride_on_index(i, strides));
    }

    return std::make_tuple(starts_abs, ends_abs, final_strides);
}

TensorShape compute_strided_slice_output_shape(TensorShape input_shape,
                                               Coordinates starts,
                                               Coordinates ends,
                                               Coordinates strides,
                                               int32_t     begin_mask,
                                               int32_t     end_mask,
                                               int32_t     shrink_axis_mask,
                                               bool        return_unshrinked)
{
    unsigned int index = 0;

    TensorShape output_shape;
    for (unsigned int i = 0; i < input_shape.num_dimensions(); ++i)
    {
        const int stride = calculate_stride_on_index(index, strides);
        const int start  = calculate_start_on_index(input_shape, i, starts, strides, begin_mask);
        const int end    = calculate_end_on_index(input_shape, i, start, ends, strides, end_mask, shrink_axis_mask);
        const int range  = end - start;

        const bool is_shrink = arm_compute::helpers::bit_ops::is_bit_set(shrink_axis_mask, i);
        if (return_unshrinked || !is_shrink)
        {
            if ((range == 0) ||               // Zero range
                (range < 0 && stride >= 0) || // Negative range with positive stride
                (range > 0 && stride <= 0))   // Positive range with negative stride
            {
                output_shape.set(index, 0);
                return output_shape;
            }
            else
            {
                int dim = range / stride + (range % stride != 0 ? 1 : 0);
                output_shape.set(index++, dim);
            }
        }
    }
    return output_shape;
}

int32_t construct_slice_end_mask(Coordinates ends)
{
    // Create end mask
    int32_t end_mask = 0;
    for (unsigned int i = 0; i < ends.num_dimensions(); ++i)
    {
        if (ends[i] < 0)
        {
            end_mask |= 1 << i;
        }
    }

    return end_mask;
}
} // namespace tensor_transform
} // namespace helpers
} // namespace arm_compute
