// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_TINT_IR_FUNCTION_H_
#define SRC_TINT_IR_FUNCTION_H_

#include <array>
#include <optional>
#include <utility>

#include "src/tint/ir/function_param.h"
#include "src/tint/ir/value.h"
#include "src/tint/type/type.h"

// Forward declarations
namespace tint::ir {
class Block;
class FunctionTerminator;
}  // namespace tint::ir

namespace tint::ir {

/// An IR representation of a function
class Function : public utils::Castable<Function, Value> {
  public:
    /// The pipeline stage for an entry point
    enum class PipelineStage {
        /// Not a pipeline entry point
        kUndefined,
        /// Vertex
        kCompute,
        /// Fragment
        kFragment,
        /// Vertex
        kVertex,
    };

    /// Attributes attached to return types
    enum class ReturnAttribute {
        /// Location attribute
        kLocation,
        /// Builtin Position attribute
        kPosition,
        /// Builtin FragDepth attribute
        kFragDepth,
        /// Builtin SampleMask
        kSampleMask,
        /// Invariant attribute
        kInvariant,
    };

    /// Constructor
    /// @param rt the function return type
    /// @param stage the function stage
    /// @param wg_size the workgroup_size
    Function(const type::Type* rt,
             PipelineStage stage = PipelineStage::kUndefined,
             std::optional<std::array<uint32_t, 3>> wg_size = {});
    ~Function() override;

    /// Sets the function stage
    /// @param stage the stage to set
    void SetStage(PipelineStage stage) { pipeline_stage_ = stage; }

    /// @returns the function pipeline stage
    PipelineStage Stage() const { return pipeline_stage_; }

    /// Sets the workgroup size
    /// @param x the x size
    /// @param y the y size
    /// @param z the z size
    void SetWorkgroupSize(uint32_t x, uint32_t y, uint32_t z) { workgroup_size_ = {x, y, z}; }

    /// @returns the workgroup size information
    std::optional<std::array<uint32_t, 3>> WorkgroupSize() const { return workgroup_size_; }

    /// @returns the return type for the function
    const type::Type* ReturnType() const { return return_type_; }

    /// Sets the return attributes
    /// @param attrs the attributes to set
    void SetReturnAttributes(utils::VectorRef<ReturnAttribute> attrs) {
        return_attributes_ = std::move(attrs);
    }
    /// @returns the return attributes
    utils::VectorRef<ReturnAttribute> ReturnAttributes() const { return return_attributes_; }

    /// Sets the return location
    /// @param loc the location to set
    void SetReturnLocation(std::optional<uint32_t> loc) { return_location_ = loc; }
    /// @returns the return location
    std::optional<uint32_t> ReturnLocation() const { return return_location_; }

    /// Sets the function parameters
    /// @param params the function paramters
    void SetParams(utils::VectorRef<FunctionParam*> params) { params_ = std::move(params); }

    /// @returns the function parameters
    utils::VectorRef<FunctionParam*> Params() const { return params_; }

    /// Sets the start target for the function
    /// @param target the start target
    void SetStartTarget(Block* target) { start_target_ = target; }
    /// @returns the function start target
    Block* StartTarget() const { return start_target_; }

  private:
    const type::Type* return_type_;
    PipelineStage pipeline_stage_;
    std::optional<std::array<uint32_t, 3>> workgroup_size_;

    utils::Vector<ReturnAttribute, 1> return_attributes_;
    std::optional<uint32_t> return_location_;

    utils::Vector<FunctionParam*, 1> params_;

    Block* start_target_ = nullptr;
};

utils::StringStream& operator<<(utils::StringStream& out, Function::PipelineStage value);
utils::StringStream& operator<<(utils::StringStream& out, Function::ReturnAttribute value);

}  // namespace tint::ir

#endif  // SRC_TINT_IR_FUNCTION_H_
