// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_TINT_LANG_SPIRV_WRITER_COMMON_FUNCTION_H_
#define SRC_TINT_LANG_SPIRV_WRITER_COMMON_FUNCTION_H_

#include <functional>

#include "src/tint/lang/spirv/writer/common/instruction.h"

namespace tint::spirv::writer {

/// A SPIR-V function
class Function {
  public:
    /// Constructor for testing purposes
    /// This creates a bad declaration, so won't generate correct SPIR-V
    Function();

    /// Constructor
    /// @param declaration the function declaration
    /// @param label_op the operand for function's entry block label
    /// @param params the function parameters
    Function(const Instruction& declaration,
             const Operand& label_op,
             const InstructionList& params);
    /// Copy constructor
    /// @param other the function to copy
    Function(const Function& other);
    /// Copy assignment operator
    /// @param other the function to copy
    /// @returns the new Function
    Function& operator=(const Function& other);
    /// Destructor
    ~Function();

    /// Iterates over the function call the cb on each instruction
    /// @param cb the callback to call
    void Iterate(std::function<void(const Instruction&)> cb) const;

    /// @returns the declaration
    const Instruction& Declaration() const { return declaration_; }

    /// @returns the label ID for the function entry block
    uint32_t LabelId() const { return std::get<uint32_t>(label_op_); }

    /// Adds an instruction to the instruction list
    /// @param op the op to set
    /// @param operands the operands for the instruction
    void PushInst(spv::Op op, const OperandList& operands) {
        instructions_.push_back(Instruction{op, operands});
    }
    /// @returns the instruction list
    const InstructionList& Instructions() const { return instructions_; }

    /// Adds a variable to the variable list
    /// @param operands the operands for the variable
    void PushVar(const OperandList& operands) {
        vars_.push_back(Instruction{spv::Op::OpVariable, operands});
    }
    /// @returns the variable list
    const InstructionList& Variables() const { return vars_; }

    /// @returns the word length of the function
    uint32_t WordLength() const {
        // 1 for the Label and 1 for the FunctionEnd
        uint32_t size = 2 + declaration_.WordLength();

        for (const auto& param : params_) {
            size += param.WordLength();
        }
        for (const auto& var : vars_) {
            size += var.WordLength();
        }
        for (const auto& inst : instructions_) {
            size += inst.WordLength();
        }
        return size;
    }

    /// @returns true if the function has a valid declaration
    explicit operator bool() const { return declaration_.Opcode() == spv::Op::OpFunction; }

  private:
    Instruction declaration_;
    Operand label_op_;
    InstructionList params_;
    InstructionList vars_;
    InstructionList instructions_;
};

}  // namespace tint::spirv::writer

#endif  // SRC_TINT_LANG_SPIRV_WRITER_COMMON_FUNCTION_H_
