// Copyright 2023 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_VALIDATOR_H_
#define SRC_TINT_IR_VALIDATOR_H_

#include <string>

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

// Forward declarations
namespace tint::ir {
class Access;
class ExitIf;
class ExitLoop;
class ExitSwitch;
class Let;
class LoadVectorElement;
class StoreVectorElement;
class Var;
}  // namespace tint::ir

namespace tint::ir {

/// Signifies the validation completed successfully
struct Success {};

/// Validates that a given IR module is correctly formed
/// @param mod the module to validate
/// @returns true on success, an error result otherwise
utils::Result<Success, diag::List> Validate(Module& mod);

/// The core IR validator.
class Validator {
  public:
    /// Create a core validator
    /// @param mod the module to be validated
    explicit Validator(Module& mod);

    /// Destructor
    ~Validator();

    /// Runs the validator over the module provided during construction
    /// @returns the results of validation, either a success result object or the diagnostics of
    /// validation failures.
    utils::Result<Success, diag::List> IsValid();

  protected:
    /// @param inst the instruction
    /// @param err the error message
    /// @returns a string with the instruction name name and error message formatted
    std::string InstError(Instruction* inst, std::string err);

    /// Adds an error for the @p inst and highlights the instruction in the disassembly
    /// @param inst the instruction
    /// @param err the error string
    void AddError(Instruction* inst, std::string err);

    /// Adds an error for the @p inst operand at @p idx and highlights the operand in the
    /// disassembly
    /// @param inst the instaruction
    /// @param idx the operand index
    /// @param err the error string
    void AddError(Instruction* inst, size_t idx, std::string err);

    /// Adds an error for the @p inst result at @p idx and highlgihts the result in the disassembly
    /// @param inst the instruction
    /// @param idx the result index
    /// @param err the error string
    void AddResultError(Instruction* inst, size_t idx, std::string err);

    /// Adds an error the @p block and highlights the block header in the disassembly
    /// @param blk the block
    /// @param err the error string
    void AddError(Block* blk, std::string err);

    /// Adds a note to @p inst and highlights the instruction in the disassembly
    /// @param inst the instruction
    /// @param err the message to emit
    void AddNote(Instruction* inst, std::string err);

    /// Adds a note to @p inst for operand @p idx and highlights the operand in the
    /// disassembly
    /// @param inst the instruction
    /// @param idx the operand index
    /// @param err the message string
    void AddNote(Instruction* inst, size_t idx, std::string err);

    /// Adds a note to @p blk and highlights the block in the disassembly
    /// @param blk the block
    /// @param err the message to emit
    void AddNote(Block* blk, std::string err);

    /// Adds an error to the diagnostics
    /// @param err the message to emit
    /// @param src the source lines to highlight
    void AddError(std::string err, Source src = {});

    /// Adds a note to the diagnostics
    /// @param note the note to emit
    /// @param src the source lines to highlight
    void AddNote(std::string note, Source src = {});

    /// @param v the value to get the name for
    /// @returns the name for the given value
    std::string Name(Value* v);

    /// Checks the given operand is not null
    /// @param inst the instruciton
    /// @param operand the operand
    /// @param idx the operand index
    void CheckOperandNotNull(ir::Instruction* inst, ir::Value* operand, size_t idx);

    /// Checks all operands in the given range (inclusive) for @p inst are not null
    /// @param inst the instruction
    /// @param start_operand the first operand to check
    /// @param end_operand the last operand to check
    void CheckOperandsNotNull(ir::Instruction* inst, size_t start_operand, size_t end_operand);

    /// Validates the root block
    /// @param blk the block
    void CheckRootBlock(Block* blk);

    /// Validates the given function
    /// @param func the function validate
    void CheckFunction(Function* func);

    /// Validates the given block
    /// @param blk the block to validate
    void CheckBlock(Block* blk);

    /// Validates the given instruction
    /// @param inst the instruction to validate
    void CheckInstruction(Instruction* inst);

    /// Validates the given var
    /// @param var the var to validate
    void CheckVar(Var* var);

    /// Validates the given let
    /// @param let the let to validate
    void CheckLet(Let* let);

    /// Validates the given call
    /// @param call the call to validate
    void CheckCall(Call* call);

    /// Validates the given access
    /// @param a the access to validate
    void CheckAccess(ir::Access* a);

    /// Validates the given binary
    /// @param b the binary to validate
    void CheckBinary(ir::Binary* b);

    /// Validates the given unary
    /// @param u the unary to validate
    void CheckUnary(ir::Unary* u);

    /// Validates the given if
    /// @param if_ the if to validate
    void CheckIf(If* if_);

    /// Validates the given loop
    /// @param l the loop to validate
    void CheckLoop(Loop* l);

    /// Validates the given switch
    /// @param s the switch to validate
    void CheckSwitch(Switch* s);

    /// Validates the given terminator
    /// @param b the terminator to validate
    void CheckTerminator(ir::Terminator* b);

    /// Validates the given exit
    /// @param e the exit to validate
    void CheckExit(ir::Exit* e);

    /// Validates the given exit if
    /// @param e the exit if to validate
    void CheckExitIf(ExitIf* e);

    /// Validates the @p exit targets a valid @p control instruction where the instruction may jump
    /// over if control instructions.
    /// @param exit the exit to validate
    /// @param control the control instruction targeted
    void CheckControlsAllowingIf(Exit* exit, Instruction* control);

    /// Validates the given exit switch
    /// @param s the exit switch to validate
    void CheckExitSwitch(ExitSwitch* s);

    /// Validates the given exit loop
    /// @param l the exit loop to validate
    void CheckExitLoop(ExitLoop* l);

    /// Validates the given load vector element
    /// @param l the load vector element to validate
    void CheckLoadVectorElement(LoadVectorElement* l);

    /// Validates the given store vector element
    /// @param s the store vector element to validate
    void CheckStoreVectorElement(StoreVectorElement* s);

    /// @param inst the instruction
    /// @param idx the operand index
    /// @returns the vector pointer type for the given instruction operand
    const type::Type* GetVectorPtrElementType(Instruction* inst, size_t idx);

  private:
    Module& mod_;
    diag::List diagnostics_;
    Disassembler dis_{mod_};

    Block* current_block_ = nullptr;
    utils::Hashset<Function*, 4> seen_functions_;
    utils::Vector<ControlInstruction*, 8> control_stack_;

    void DisassembleIfNeeded();
};

}  // namespace tint::ir

#endif  // SRC_TINT_IR_VALIDATOR_H_
