/*
 * Copyright (c) 2016-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.
 */
namespace arm_compute
{
inline Window::Window(const Window &src)
    : _dims(), _is_broadcasted(utility::generate_array<bool, Coordinates::num_max_dimensions, false>::value)
{
    for(size_t i = 0; i < Coordinates::num_max_dimensions; ++i)
    {
        set(i, src[i]);
        _is_broadcasted[i] = src.is_broadcasted(i);
    }
}

inline Window &Window::operator=(const arm_compute::Window &rhs)
{
    Window tmp(rhs);
    swap(*this, tmp);
    return *this;
}

inline constexpr const Window::Dimension &Window::operator[](size_t dimension) const
{
    // Precondition: dimension < Coordinates::num_max_dimensions
    return _dims.at(dimension);
}

inline void Window::set(size_t dimension, const Window::Dimension &dim)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    _dims[dimension] = dim;
}

inline void Window::set_broadcasted(size_t dimension)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    set(dimension, Dimension(0, 0, 0));
    _is_broadcasted[dimension] = true;
}

inline bool Window::is_broadcasted(size_t dimension) const
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    return _is_broadcasted[dimension];
}

inline Window Window::collapse_if_possible(const Window &full_window, const size_t first,
                                           const size_t last, bool *has_collapsed) const
{
    Window collapsed(*this);

    bool is_collapsable = true;
    int  collapsed_end  = _dims[first].end();

    for(size_t d = first + 1; is_collapsable && (d < last); ++d)
    {
        // The _dims's dimension must match the full _dims dimension to be collapsable:
        is_collapsable = (_dims[d].start() == 0) && (full_window[d].start() == 0) && (_dims[d].step() <= 1)
                         && (full_window[d].end() == _dims[d].end());
        collapsed_end *= _dims[d].end();
    }

    if(is_collapsable)
    {
        collapsed._dims.at(first).set_end(collapsed_end);
        for(size_t d = first + 1; is_collapsable && (d < last); ++d)
        {
            collapsed.set(d, Dimension());
        }
    }

    if(has_collapsed != nullptr)
    {
        *has_collapsed = is_collapsable;
    }

    return collapsed;
}

inline Window Window::shift_dimensions(unsigned int shift_value) const
{
    Window shifted_window;
    for(size_t n = 0; n < (Coordinates::num_max_dimensions - shift_value); n++)
    {
        shifted_window.set(n, _dims[n + shift_value]);
    }
    return shifted_window;
}

inline Window Window::collapse(const Window &full_window, const size_t first, const size_t last) const
{
    bool   has_collapsed = false;
    Window collapsed     = collapse_if_possible(full_window, first, last, &has_collapsed);
    // Make sure that the window has collapsed
    ARM_COMPUTE_ERROR_ON(!has_collapsed);
    return collapsed;
}

inline Window Window::broadcast_if_dimension_le_one(const TensorShape &shape) const
{
    Window broadcastWin(*this);
    for(size_t d = 0; d < TensorShape::num_max_dimensions; ++d)
    {
        if(shape[d] <= 1)
        {
            broadcastWin.set_broadcasted(d);
        }
    }
    return broadcastWin;
}

inline void Window::shift(size_t dimension, int shift_value)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    Window::Dimension &d = _dims[dimension];
    d                    = Window::Dimension(d.start() + shift_value, d.end() + shift_value, d.step());
}

inline void Window::adjust(size_t dimension, int adjust_value, bool is_at_start)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    Window::Dimension &d = _dims[dimension];

    if(is_at_start)
    {
        d = Window::Dimension(d.start() + adjust_value, d.end(), d.step());
    }
    else
    {
        d = Window::Dimension(d.start(), d.end() + adjust_value, d.step());
    }
}

inline void Window::scale(size_t dimension, float scale_value)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    Window::Dimension &d            = _dims[dimension];
    const int          scaled_step  = d.step() * scale_value;
    const int          scaled_start = d.start() * scale_value;
    const int          scaled_diff  = (d.end() - d.start()) * scale_value;
    const int          scaled_end   = scaled_start + ceil_to_multiple(scaled_diff, scaled_step);

    d = Window::Dimension(scaled_start, scaled_end, scaled_step);
}

inline void Window::set_dimension_step(size_t dimension, int step)
{
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
    _dims[dimension].set_step(step);
}

inline void Window::validate() const
{
    for(size_t i = 0; i < Coordinates::num_max_dimensions; ++i)
    {
        ARM_COMPUTE_ERROR_ON(_dims[i].end() < _dims[i].start());
        ARM_COMPUTE_ERROR_ON((_dims[i].step() != 0) && (((_dims[i].end() - _dims[i].start()) % _dims[i].step()) != 0));
    }
}

inline constexpr size_t Window::num_iterations(size_t dimension) const
{
    // Precondition: dimension < Coordinates::num_max_dimensions
    // Precondition: (end - start) % step == 0
    return (_dims.at(dimension).end() - _dims.at(dimension).start()) / _dims.at(dimension).step();
}

inline Window Window::split_window(size_t dimension, size_t id, size_t total) const
{
    ARM_COMPUTE_ERROR_ON(id >= total);
    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);

    Window out;

    for(size_t d = 0; d < Coordinates::num_max_dimensions; ++d)
    {
        if(d == dimension)
        {
            int start        = _dims[d].start();
            int end          = _dims[d].end();
            const int step   = _dims[d].step();

            const int num_it = num_iterations(d);
            const int rem    = num_it % total;
            int work         = num_it / total;

            int it_start     = work * id;

            if(int(id) < rem)
            {
                ++work;
                it_start += id;
            }
            else
            {
                it_start += rem;
            }

            start += it_start * step;
            end = std::min(end, start + work * step);

            out.set(d, Dimension(start, end, step));
        }
        else
        {
            out.set(d, _dims[d]);
        }
    }

    return out;
}

template <unsigned int window_dimension>
inline bool Window::slide_window_slice(Window &slice) const
{
    for(unsigned int n = window_dimension; n < Coordinates::num_max_dimensions; ++n)
    {
        // Did we reach the end of this dimension?
        const int v = slice._dims[n].start() + 1;

        if(v < _dims[n].end())
        {
            // No: increment
            slice._dims[n] = Dimension(v, v + 1, 1);

            // Reset lower dimensions:
            for(unsigned int lower = window_dimension; lower < n; ++lower)
            {
                slice._dims[lower] = Dimension(_dims[lower].start(), _dims[lower].start() + 1, 1);
            }
            return true;
        }
    }

    // It was the last slice
    return false; // Iteration over
}

template <unsigned int window_dimension>
inline Window          Window::first_slice_window() const
{
    Window slice;

    std::copy_n(_dims.begin(), window_dimension, slice._dims.begin());

    //Initialise higher dimensions to be the first slice.
    for(unsigned int n = window_dimension; n < Coordinates::num_max_dimensions; ++n)
    {
        slice._dims[n] = Dimension(_dims[n].start(), _dims[n].start() + 1, 1);
    }

    return slice;
}

inline void Window::use_tensor_dimensions(const TensorShape &shape, size_t first_dimension)
{
    for(unsigned int n = first_dimension; n < shape.num_dimensions(); ++n)
    {
        set(n, Window::Dimension(0, std::max(shape[n], static_cast<uint32_t>(1))));
    }
}

inline TensorShape Window::shape() const
{
    TensorShape shape;
    for(size_t d = 0; d < TensorShape::num_max_dimensions; ++d)
    {
        shape.set(d, (_dims[d].end() - _dims[d].start()) / _dims[d].step());
    }
    return shape;
}

inline size_t Window::num_iterations_total() const
{
    size_t total = 1;
    for(size_t d = 0; d < Coordinates::num_max_dimensions; ++d)
    {
        total *= num_iterations(d);
    }
    return total;
}

inline void swap(Window &lhs, Window &rhs)
{
    lhs._dims.swap(rhs._dims);
}
} // namespace arm_compute
