// Copyright 2022 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_CORE_IR_DISASSEMBLY_H_
#define SRC_TINT_LANG_CORE_IR_DISASSEMBLY_H_

#include <memory>
#include <string>
#include <string_view>

#include "src/tint/lang/core/binary_op.h"
#include "src/tint/lang/core/ir/binary.h"
#include "src/tint/lang/core/ir/block.h"
#include "src/tint/lang/core/ir/block_param.h"
#include "src/tint/lang/core/ir/if.h"
#include "src/tint/lang/core/ir/loop.h"
#include "src/tint/lang/core/ir/module.h"
#include "src/tint/lang/core/ir/switch.h"
#include "src/tint/lang/core/ir/unary.h"
#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/containers/hashset.h"
#include "src/tint/utils/text/styled_text.h"

// Forward declarations.
namespace tint::core::type {
class Struct;
}

namespace tint::core::ir {

/// Disassembly holds the disassembly of an IR module.
class Disassembly {
  public:
    /// A reference to an instruction's operand or result.
    struct IndexedValue {
        /// The instruction that is using the value;
        const Instruction* instruction = nullptr;
        /// The index of the operand that is the value being used.
        size_t index = 0u;

        /// @returns the hash code of the IndexedValue
        tint::HashCode HashCode() const { return Hash(instruction, index); }

        /// An equality helper for IndexedValue.
        /// @param other the IndexedValue to compare against
        /// @returns true if the two IndexedValues are equal
        bool operator==(const IndexedValue& other) const {
            return instruction == other.instruction && index == other.index;
        }
    };

    /// Constructor.
    /// Performs the disassembly of the module @p mod, constructing a Source::File with the name @p
    /// file_name.
    /// @param mod the module to disassemble
    Disassembly(const Module& mod, std::string_view file_name);

    /// Move constructor
    Disassembly(Disassembly&&);

    /// Destructor
    ~Disassembly();

    /// @returns the string representation of the module
    const StyledText& Text() const { return out_; }

    /// @returns the string representation of the module as plain-text
    std::string Plain() const { return out_.Plain(); }

    /// @returns the disassembly file
    const std::shared_ptr<Source::File>& File() const { return file_; }

    /// @returns the disassembled name for the Block @p blk
    StyledText NameOf(const Block* blk);

    /// @returns the disassembled name for the Value @p node
    StyledText NameOf(const Value* node);

    /// @returns the disassembled name for the If @p inst
    StyledText NameOf(const If* inst);

    /// @returns the disassembled name for the Loop @p inst
    StyledText NameOf(const Loop* inst);

    /// @returns the disassembled name for the Switch @p inst
    StyledText NameOf(const Switch* inst);

    /// @returns the disassembled name for the BinaryOp @p op
    StyledText NameOf(BinaryOp op);

    /// @returns the disassembled name for the UnaryOp @p op
    StyledText NameOf(UnaryOp op);

    /// @param inst the instruction to retrieve
    /// @returns the source for the instruction
    Source InstructionSource(const Instruction* inst) const {
        return instruction_to_src_.GetOr(inst, Source{});
    }

    /// @param operand the operand to retrieve
    /// @returns the source for the operand
    Source OperandSource(IndexedValue operand) const {
        return operand_to_src_.GetOr(operand, Source{});
    }

    /// @param result the result to retrieve
    /// @returns the source for the result
    Source ResultSource(IndexedValue result) const {
        return result_to_src_.GetOr(result, Source{});
    }

    /// @param blk the block to retrieve
    /// @returns the source for the block
    Source BlockSource(const Block* blk) const { return block_to_src_.GetOr(blk, Source{}); }

    /// @param param the block parameter to retrieve
    /// @returns the source for the parameter
    Source BlockParamSource(const BlockParam* param) {
        return block_param_to_src_.GetOr(param, Source{});
    }

    /// @param func the function to retrieve
    /// @returns the source for the function
    Source FunctionSource(const Function* func) { return function_to_src_.GetOr(func, Source{}); }

    /// @param param the function parameter to retrieve
    /// @returns the source for the parameter
    Source FunctionParamSource(const FunctionParam* param) {
        return function_param_to_src_.GetOr(param, Source{});
    }

  private:
    /// Performs the disassembling of the module.
    void Disassemble();

    /// Stores the given @p src location for @p inst instruction
    /// @param inst the instruction to store
    /// @param src the source location
    void SetSource(const Instruction* inst, Source src) { instruction_to_src_.Add(inst, src); }

    /// Stores the given @p src location for @p blk block
    /// @param blk the block to store
    /// @param src the source location
    void SetSource(const Block* blk, Source src) { block_to_src_.Add(blk, src); }

    /// Stores the given @p src location for @p param block parameter
    /// @param param the block parameter to store
    /// @param src the source location
    void SetSource(const BlockParam* param, Source src) { block_param_to_src_.Add(param, src); }

    /// Stores the given @p src location for @p func function
    /// @param func the function to store
    /// @param src the source location
    void SetSource(const Function* func, Source src) { function_to_src_.Add(func, src); }

    /// Stores the given @p src location for @p param function parameter
    /// @param param the function parameter to store
    /// @param src the source location
    void SetSource(const FunctionParam* param, Source src) {
        function_param_to_src_.Add(param, src);
    }

    /// Stores the given @p src location for @p op operand
    /// @param op the operand to store
    /// @param src the source location
    void SetSource(IndexedValue op, Source src) { operand_to_src_.Add(op, src); }

    /// Stores the given @p src location for @p result
    /// @param result the result to store
    /// @param src the source location
    void SetResultSource(IndexedValue result, Source src) { result_to_src_.Add(result, src); }

    /// @returns the source location for the current emission location
    Source::Location MakeCurrentLocation();

    class SourceMarker {
      public:
        explicit SourceMarker(Disassembly* d) : dis_(d), begin_(dis_->MakeCurrentLocation()) {}
        ~SourceMarker() = default;

        void Store(const Instruction* inst) { dis_->SetSource(inst, MakeSource()); }

        void Store(const Block* blk) { dis_->SetSource(blk, MakeSource()); }

        void Store(const BlockParam* param) { dis_->SetSource(param, MakeSource()); }

        void Store(const Function* func) { dis_->SetSource(func, MakeSource()); }

        void Store(const FunctionParam* param) { dis_->SetSource(param, MakeSource()); }

        void Store(IndexedValue operand) { dis_->SetSource(operand, MakeSource()); }

        void StoreResult(IndexedValue result) { dis_->SetResultSource(result, MakeSource()); }

        Source MakeSource() const {
            return Source(Source::Range(begin_, dis_->MakeCurrentLocation()));
        }

      private:
        Disassembly* dis_ = nullptr;
        Source::Location begin_;
    };

    StyledText& Indent();

    void EmitBlock(const Block* blk, std::string_view comment = "");
    void EmitFunction(const Function* func);
    void EmitParamAttributes(const FunctionParam* p);
    void EmitReturnAttributes(const Function* func);
    void EmitBindingPoint(BindingPoint p);
    void EmitLocation(Location loc);
    void EmitInstruction(const Instruction* inst);
    void EmitValueWithType(const Instruction* val);
    void EmitValueWithType(const Value* val);
    void EmitValue(const Value* val);
    void EmitBinary(const Binary* b);
    void EmitUnary(const Unary* b);
    void EmitTerminator(const Terminator* b);
    void EmitSwitch(const Switch* s);
    void EmitLoop(const Loop* l);
    void EmitIf(const If* i);
    void EmitStructDecl(const core::type::Struct* str);
    void EmitLine();
    void EmitOperand(const Instruction* inst, size_t index);
    void EmitOperandList(const Instruction* inst, size_t start_index = 0);
    void EmitOperandList(const Instruction* inst, size_t start_index, size_t count);
    void EmitInstructionName(const Instruction* inst);

    const Module& mod_;
    StyledText out_;
    std::shared_ptr<Source::File> file_;
    uint32_t indent_size_ = 0;
    bool in_function_ = false;

    uint32_t current_output_line_ = 1;
    uint32_t current_output_start_pos_ = 0;

    Hashmap<const Block*, Source, 8> block_to_src_;
    Hashmap<const BlockParam*, Source, 8> block_param_to_src_;
    Hashmap<const Instruction*, Source, 8> instruction_to_src_;
    Hashmap<IndexedValue, Source, 8> operand_to_src_;
    Hashmap<IndexedValue, Source, 8> result_to_src_;
    Hashmap<const Function*, Source, 8> function_to_src_;
    Hashmap<const FunctionParam*, Source, 8> function_param_to_src_;

    // Names / IDs
    Hashmap<const Block*, size_t, 32> block_ids_;
    Hashmap<const Value*, std::string, 32> value_ids_;
    Hashmap<const If*, std::string, 8> if_names_;
    Hashmap<const Loop*, std::string, 8> loop_names_;
    Hashmap<const Switch*, std::string, 8> switch_names_;
    Hashset<std::string, 32> ids_;
};

/// @returns the disassembly for the module @p mod, using the file name @p file_name
inline Disassembly Disassemble(const Module& mod, std::string_view file_name = "") {
    return Disassembly(mod, file_name);
}

}  // namespace tint::core::ir

#endif  // SRC_TINT_LANG_CORE_IR_DISASSEMBLY_H_
