// 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_BUILDER_IMPL_H_
#define SRC_TINT_IR_BUILDER_IMPL_H_

#include <string>
#include <unordered_map>
#include <utility>

#include "src/tint/diagnostic/diagnostic.h"
#include "src/tint/ir/builder.h"
#include "src/tint/ir/flow_node.h"
#include "src/tint/ir/module.h"
#include "src/tint/utils/result.h"

// Forward Declarations
namespace tint {
class Program;
}  // namespace tint
namespace tint::ast {
class BlockStatement;
class BreakIfStatement;
class BreakStatement;
class ContinueStatement;
class Function;
class IfStatement;
class LoopStatement;
class ReturnStatement;
class Statement;
}  // namespace tint::ast
namespace tint::ir {
class Block;
class If;
class Function;
class Loop;
class Switch;
class Terminator;
}  // namespace tint::ir

namespace tint::ir {

/// Builds an ir::Module from a given ast::Program
class BuilderImpl {
  public:
    /// Constructor
    /// @param program the program to create from
    explicit BuilderImpl(const Program* program);
    /// Destructor
    ~BuilderImpl();

    /// Builds an ir::Module from the given Program
    /// @returns true on success, false otherwise
    utils::Result<Module> Build();

    /// @returns the error
    std::string error() const { return diagnostics_.str(); }

    /// Emits a function to the IR.
    /// @param func the function to emit
    /// @returns true if successful, false otherwise
    bool EmitFunction(const ast::Function* func);

    /// Emits a set of statements to the IR.
    /// @param stmts the statements to emit
    /// @returns true if successful, false otherwise.
    bool EmitStatements(utils::VectorRef<const ast::Statement*> stmts);

    /// Emits a statement to the IR
    /// @param stmt the statment to emit
    /// @returns true on success, false otherwise.
    bool EmitStatement(const ast::Statement* stmt);

    /// Emits a block statement to the IR.
    /// @param block the block to emit
    /// @returns true if successful, false otherwise.
    bool EmitBlock(const ast::BlockStatement* block);

    /// Emits an if control node to the IR.
    /// @param stmt the if statement
    /// @returns true if successful, false otherwise.
    bool EmitIf(const ast::IfStatement* stmt);

    /// Emits a return node to the IR.
    /// @param stmt the return AST statement
    /// @returns true if successful, false otherwise.
    bool EmitReturn(const ast::ReturnStatement* stmt);

    /// Emits a loop control node to the IR.
    /// @param stmt the loop statement
    /// @returns true if successful, false otherwise.
    bool EmitLoop(const ast::LoopStatement* stmt);

    /// Emits a break statement
    /// @param stmt the break statement
    /// @returns true if successfull, false otherwise.
    bool EmitBreak(const ast::BreakStatement* stmt);

    /// Emits a continue statement
    /// @param stmt the continue statement
    /// @returns true if successfull, false otherwise.
    bool EmitContinue(const ast::ContinueStatement* stmt);

    /// Emits a break-if statement
    /// @param stmt the break-if statement
    /// @returns true if successfull, false otherwise.
    bool EmitBreakIf(const ast::BreakIfStatement* stmt);

    /// Retrieve the IR Flow node for a given AST node.
    /// @param n the node to lookup
    /// @returns the FlowNode for the given ast::Node or nullptr if it doesn't exist.
    const ir::FlowNode* FlowNodeForAstNode(const ast::Node* n) const {
        if (ast_to_flow_.count(n) == 0) {
            return nullptr;
        }
        return ast_to_flow_.at(n);
    }

    /// The stack of flow control blocks.
    utils::Vector<FlowNode*, 8> flow_stack;

  private:
    enum class ControlFlags { kNone, kExcludeSwitch };

    void BranchTo(const ir::FlowNode* node);
    void BranchToIfNeeded(const ir::FlowNode* node);

    FlowNode* FindEnclosingControl(ControlFlags flags);

    Builder builder_;

    diag::List diagnostics_;

    Block* current_flow_block_ = nullptr;
    Function* current_function_ = nullptr;

    /// Map from ast nodes to flow nodes, used to retrieve the flow node for a given AST node.
    /// Used for testing purposes.
    std::unordered_map<const ast::Node*, const FlowNode*> ast_to_flow_;
};

}  // namespace tint::ir

#endif  // SRC_TINT_IR_BUILDER_IMPL_H_
