// 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_BLOCK_H_
#define SRC_TINT_IR_BLOCK_H_

#include <utility>

#include "src/tint/ir/instruction.h"
#include "src/tint/ir/terminator.h"
#include "src/tint/utils/vector.h"

// Forward declarations
namespace tint::ir {
class ControlInstruction;
}  // namespace tint::ir

namespace tint::ir {

/// A block of statements. The instructions in the block are a linear list of instructions to
/// execute. The block will terminate with a Terminator instruction at the end.
class Block : public utils::Castable<Block> {
  public:
    /// Constructor
    Block();
    ~Block() override;

    /// @returns true if this is block has a terminator instruction
    bool HasTerminator() {
        return instructions_.last != nullptr && instructions_.last->Is<ir::Terminator>();
    }

    /// @return the terminator instruction for this block
    ir::Terminator* Terminator() {
        if (!HasTerminator()) {
            return nullptr;
        }
        return instructions_.last->As<ir::Terminator>();
    }

    /// @returns the instructions in the block
    Instruction* Instructions() { return instructions_.first; }

    /// Iterator for the instructions inside a block
    class Iterator {
      public:
        /// Constructor
        /// @param inst the instruction to start iterating from
        explicit Iterator(Instruction* inst) : inst_(inst) {}
        ~Iterator() = default;

        /// Dereference operator
        /// @returns the instruction for this iterator
        Instruction* operator*() const { return inst_; }

        /// Comparison operator
        /// @param itr to compare against
        /// @returns true if this iterator and @p itr point to the same instruction
        bool operator==(const Iterator& itr) const { return itr.inst_ == inst_; }

        /// Not equal operator
        /// @param itr to compare against
        /// @returns true if this iterator and @p itr point to different instructions
        bool operator!=(const Iterator& itr) const { return !(*this == itr); }

        /// Increment operator
        /// @returns this iterator advanced to the next element
        Iterator& operator++() {
            inst_ = inst_->next;
            return *this;
        }

      private:
        Instruction* inst_ = nullptr;
    };

    /// @returns the iterator pointing to the start of the instruction list
    Iterator begin() { return Iterator{instructions_.first}; }

    /// @returns the ending iterator
    Iterator end() { return Iterator{nullptr}; }

    /// @returns the first instruction in the instruction list
    Instruction* Front() { return instructions_.first; }

    /// @returns the last instruction in the instruction list
    Instruction* Back() { return instructions_.last; }

    /// Adds the instruction to the beginning of the block
    /// @param inst the instruction to add
    /// @returns the instruction to allow calls to be chained
    Instruction* Prepend(Instruction* inst);
    /// Adds the instruction to the end of the block
    /// @param inst the instruction to add
    /// @returns the instruction to allow calls to be chained
    Instruction* Append(Instruction* inst);
    /// Adds the new instruction before the given instruction
    /// @param before the instruction to insert before
    /// @param inst the instruction to insert
    void InsertBefore(Instruction* before, Instruction* inst);
    /// Adds the new instruction after the given instruction
    /// @param after the instruction to insert after
    /// @param inst the instruction to insert
    void InsertAfter(Instruction* after, Instruction* inst);
    /// Replaces the target instruction with the new instruction
    /// @param target the instruction to replace
    /// @param inst the instruction to insert
    void Replace(Instruction* target, Instruction* inst);
    /// Removes the target instruction
    /// @param inst the instruction to remove
    void Remove(Instruction* inst);

    /// @returns true if the block contains no instructions
    bool IsEmpty() { return Length() == 0; }

    /// @returns the number of instructions in the block
    size_t Length() { return instructions_.count; }

    /// @return the parent instruction that owns this block
    ControlInstruction* Parent() { return parent_; }

    /// @param parent the parent instruction that owns this block
    void SetParent(ControlInstruction* parent) { parent_ = parent; }

  private:
    struct {
        Instruction* first = nullptr;
        Instruction* last = nullptr;
        size_t count = 0;
    } instructions_;

    ControlInstruction* parent_ = nullptr;
};

}  // namespace tint::ir

#endif  // SRC_TINT_IR_BLOCK_H_
