/*
 * Copyright (c) 2017-2021 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/SubTensorInfo.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/Validate.h"

namespace arm_compute
{
namespace
{
/** Extends parent shape depending on subtensor's coordinates and shape
 *
 * @param parent_shape Parent shape
 * @param shape        Subtensor shape
 * @param coords       Subtensor coordinates inside parent tensor
 *
 * @return Extended parent shape
 */
TensorShape extend_parent_shape(TensorShape parent_shape, TensorShape shape, Coordinates coords)
{
    // Extend shape
    for(unsigned int i = 0; i < TensorShape::num_max_dimensions; ++i)
    {
        int dimension_extend = coords[i] + static_cast<int>(shape[i]);
        if((dimension_extend > static_cast<int>(parent_shape[i])) && (dimension_extend > 0))
        {
            parent_shape.set(i, static_cast<size_t>(dimension_extend));
        }
    }

    return parent_shape;
}
} // namespace

SubTensorInfo::SubTensorInfo()
    : _parent(nullptr), _tensor_shape(), _dims_state(), _coords(), _valid_region{ Coordinates(), _tensor_shape }, _extend_parent(false)
{
}

SubTensorInfo::SubTensorInfo(ITensorInfo *parent, TensorShape tensor_shape, Coordinates coords, bool extend_parent)
    : _parent(parent), _tensor_shape(tensor_shape), _dims_state(), _coords(coords), _valid_region{ Coordinates(), _tensor_shape }, _extend_parent(extend_parent)
{
    ARM_COMPUTE_ERROR_ON(parent == nullptr);

    // Check if subtensor is valid if parent is configured
    if(parent->tensor_shape().total_size() != 0 && !_extend_parent)
    {
        ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(parent->tensor_shape(), coords, tensor_shape);
    }

    // Initialize valid region
    _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
}

std::unique_ptr<ITensorInfo> SubTensorInfo::clone() const
{
    // Clone creates a TensorInfo object from SubTensorInfo's parent which will conclude to a TensorInfo
    // For now it does not make sense to copy a SubTensorInfo explicitly
    ARM_COMPUTE_ERROR_ON(_parent == nullptr);
    auto clone_obj = _parent->clone();
    clone_obj->set_tensor_shape(_tensor_shape);
    clone_obj->set_valid_region(_valid_region);
    return clone_obj;
}

ITensorInfo &SubTensorInfo::set_tensor_shape(const TensorShape &shape)
{
    ARM_COMPUTE_ERROR_ON(_parent == nullptr);

    // Check if subtensor is valid if parent is configured
    if(_parent->tensor_shape().total_size() != 0 && !_extend_parent)
    {
        ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(_parent->tensor_shape(), _coords, shape);
        _valid_region = ValidRegion{ _coords, shape };
    }
    else if(_extend_parent) // Extend parent shape, configure if specified
    {
        ARM_COMPUTE_ERROR_ON((_parent->data_type() == DataType::UNKNOWN) && (_parent->format() == Format::UNKNOWN));
        TensorShape parent_extended_shape = extend_parent_shape(_parent->tensor_shape(), shape, _coords);
        _parent->set_tensor_shape(parent_extended_shape);
        _parent->set_valid_region(ValidRegion{ Coordinates(), parent_extended_shape });
    }
    _tensor_shape = shape;
    return *this;
}

ITensorInfo &SubTensorInfo::set_tensor_dims_state(const TensorDimsState &state)
{
    ARM_COMPUTE_ERROR_ON(_parent == nullptr);
    _dims_state = state;
    return *this;
}

bool SubTensorInfo::extend_padding(const PaddingSize &padding)
{
    ARM_COMPUTE_ERROR_ON(_parent == nullptr);
    ARM_COMPUTE_ERROR_ON(!_parent->is_resizable());
    ARM_COMPUTE_ERROR_ON(_parent->total_size() == 0);

    // Check that you do not extend padding on sub-tensors unless XY shape matches parent tensor
    // TODO(COMPMID-3558): Remove _extend_parent check
    if(!_extend_parent && (padding.left || padding.right))
    {
        ARM_COMPUTE_ERROR_ON(_parent->tensor_shape().x() != tensor_shape().x());
    }
    if(!_extend_parent && (padding.top || padding.bottom))
    {
        ARM_COMPUTE_ERROR_ON(_parent->tensor_shape().y() != tensor_shape().y());
    }

    // Extend parent padding if required
    return _parent->extend_padding(padding);
}

int32_t SubTensorInfo::offset_element_in_bytes(const Coordinates &pos) const
{
    ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(pos, _tensor_shape.num_dimensions());

    int32_t        offset  = offset_first_element_in_bytes();
    const Strides &strides = strides_in_bytes();

    for(size_t i = 0; i < _tensor_shape.num_dimensions(); ++i)
    {
        offset += pos[i] * strides[i];
    }

    return offset;
}
} // namespace arm_compute
