/*
 * Copyright (c) 2023 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.
 */

#ifndef CKW_PROTOTYPE_INCLUDE_CKW_TENSORTILESAMPLER_H
#define CKW_PROTOTYPE_INCLUDE_CKW_TENSORTILESAMPLER_H

#include "ckw/types/TensorSamplerTypes.h"

#include <functional>

namespace ckw
{

class TileOperand;

/** Tensor sampler
 *
 * It contains information about how the result tile should be stored to tensor memory.
 * It can also be used to dictate how the subsequent operators fetch the input tensor.
 */
class TensorTileSampler
{
public:
    /** Initialize a new instance of @ref TensorSampler class. */
    TensorTileSampler();

    /** Initialize a new instance of @ref TensorSampler class.
     *
     * @param[in] x              The coordinate in the x dimension.
     * @param[in] y              The coordinate in the y dimension.
     * @param[in] z              The coordinate in the z dimension.
     * @param[in] b              The coordinate in the batch dimension.
     * @param[in] format         The tensor data format.
     * @param[in] address_mode_x The address mode of the x dimension.
     * @param[in] address_mode_y The address mode of the y dimension.
     * @param[in] address_mode_z The address mode of the z dimension.
     */
    TensorTileSampler(TileOperand              &x,
                      TileOperand              &y,
                      TileOperand              &z,
                      TileOperand              &b,
                      TensorSamplerFormat       format,
                      TensorSamplerAddressModeX address_mode_x,
                      TensorSamplerAddressModeY address_mode_y,
                      TensorSamplerAddressModeZ address_mode_z);

    /** Initialize a new instance of @ref TensorSampler class.
     *
     * @param[in] x              The coordinate in the x dimension.
     * @param[in] y              The coordinate in the y dimension.
     * @param[in] z              The coordinate in the z dimension.
     * @param[in] b              The coordinate in the batch dimension.
     * @param[in] height         The height of the tile.
     * @param[in] width          The width of the tile.
     * @param[in] format         The tensor data format.
     * @param[in] address_mode_x The address mode of the x dimension.
     * @param[in] address_mode_y The address mode of the y dimension.
     * @param[in] address_mode_z The address mode of the z dimension.
     */
    TensorTileSampler(TileOperand              &x,
                      TileOperand              &y,
                      TileOperand              &z,
                      TileOperand              &b,
                      int32_t                   height,
                      int32_t                   width,
                      TensorSamplerFormat       format,
                      TensorSamplerAddressModeX address_mode_x,
                      TensorSamplerAddressModeY address_mode_y,
                      TensorSamplerAddressModeZ address_mode_z);

    /** Get the coordinate in the x dimension. */
    const TileOperand &x() const;

    /** Set the coordinate in the x dimension. */
    TensorTileSampler &x(TileOperand &x);

    /** Get the coordinate in the y dimension. */
    const TileOperand &y() const;

    /** Set the coordinate in the y dimension. */
    TensorTileSampler &y(TileOperand &y);

    /** Get the coordinate in the z dimension. */
    const TileOperand &z() const;

    /** Set the coordinate in the z dimension. */
    TensorTileSampler &z(TileOperand &z);

    /** Get the coordinate in the batch dimension. */
    const TileOperand &b() const;

    /** Set the coordinate in the batch dimension. */
    TensorTileSampler &b(TileOperand &b);

    /** Get the width of the tile. */
    int32_t width() const;

    /** Set the width of the tile. */
    TensorTileSampler &width(int32_t width);

    /** Get the height of the tile. */
    int32_t height() const;

    /** Set the height of the tile. */
    TensorTileSampler &height(int32_t height);

    /** Get the format of the tensor. */
    TensorSamplerFormat format() const;

    /** Set the format of the tensor. */
    TensorTileSampler &format(TensorSamplerFormat format);

    /** Get the address mode of the x dimension. */
    TensorSamplerAddressModeX address_mode_x() const;

    /** Set the address mode of the x-dimension. */
    TensorTileSampler &address_mode_x(TensorSamplerAddressModeX address_mode_x);

    /** Get the address mode of the y dimension. */
    TensorSamplerAddressModeY address_mode_y() const;

    /** Set the address mode of the y dimension. */
    TensorTileSampler &address_mode_y(TensorSamplerAddressModeY address_mode_y);

    /** Get the address mode of the z dimension. */
    TensorSamplerAddressModeZ address_mode_z() const;

    /** Set the address mode of the z dimension. */
    TensorTileSampler &address_mode_z(TensorSamplerAddressModeZ address_mode_z);

private:
    TileOperand *_x{nullptr};
    TileOperand *_y{nullptr};
    TileOperand *_z{nullptr};
    TileOperand *_b{nullptr};

    int32_t _height{0};
    int32_t _width{0};

    TensorSamplerFormat       _format{TensorSamplerFormat::Unknown};
    TensorSamplerAddressModeX _address_mode_x{TensorSamplerAddressModeX::Unknown};
    TensorSamplerAddressModeY _address_mode_y{TensorSamplerAddressModeY::Unknown};
    TensorSamplerAddressModeZ _address_mode_z{TensorSamplerAddressModeZ::Unknown};
};

} // namespace ckw

#endif // CKW_PROTOTYPE_INCLUDE_CKW_TENSORTILESAMPLER_H
