// 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.

#include "src/tint/ir/disassembler.h"

#include "src//tint/ir/unary.h"
#include "src/tint/constant/composite.h"
#include "src/tint/constant/scalar.h"
#include "src/tint/constant/splat.h"
#include "src/tint/ir/binary.h"
#include "src/tint/ir/bitcast.h"
#include "src/tint/ir/block.h"
#include "src/tint/ir/builtin.h"
#include "src/tint/ir/construct.h"
#include "src/tint/ir/convert.h"
#include "src/tint/ir/discard.h"
#include "src/tint/ir/function_terminator.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
#include "src/tint/ir/root_terminator.h"
#include "src/tint/ir/store.h"
#include "src/tint/ir/switch.h"
#include "src/tint/ir/user_call.h"
#include "src/tint/ir/var.h"
#include "src/tint/switch.h"
#include "src/tint/type/type.h"
#include "src/tint/utils/scoped_assignment.h"

namespace tint::ir {
namespace {

class ScopedStopNode {
  public:
    ScopedStopNode(std::unordered_set<const FlowNode*>* stop_nodes, const FlowNode* node)
        : stop_nodes_(stop_nodes), node_(node) {
        stop_nodes_->insert(node_);
    }

    ~ScopedStopNode() { stop_nodes_->erase(node_); }

  private:
    std::unordered_set<const FlowNode*>* stop_nodes_;
    const FlowNode* node_;
};

class ScopedIndent {
  public:
    explicit ScopedIndent(uint32_t* indent) : indent_(indent) { (*indent_) += 2; }

    ~ScopedIndent() { (*indent_) -= 2; }

  private:
    uint32_t* indent_;
};

}  // namespace

Disassembler::Disassembler(const Module& mod) : mod_(mod) {}

Disassembler::~Disassembler() = default;

utils::StringStream& Disassembler::Indent() {
    for (uint32_t i = 0; i < indent_size_; i++) {
        out_ << " ";
    }
    return out_;
}

void Disassembler::EmitBlockInstructions(const Block* b) {
    for (const auto* inst : b->instructions) {
        Indent();
        EmitInstruction(inst);
        out_ << std::endl;
    }
}

size_t Disassembler::GetIdForNode(const FlowNode* node) {
    TINT_ASSERT(IR, node);

    auto it = flow_node_to_id_.find(node);
    if (it != flow_node_to_id_.end()) {
        return it->second;
    }
    size_t id = next_node_id_++;
    flow_node_to_id_[node] = id;
    return id;
}

void Disassembler::Walk(const FlowNode* node) {
    if ((visited_.count(node) > 0) || (stop_nodes_.count(node) > 0)) {
        return;
    }
    visited_.insert(node);

    tint::Switch(
        node,
        [&](const ir::Function* f) {
            TINT_SCOPED_ASSIGNMENT(in_function_, true);

            Indent() << "%fn" << GetIdForNode(f) << " = func " << f->name.Name()
                     << "():" << f->return_type->FriendlyName();

            if (f->pipeline_stage != Function::PipelineStage::kUndefined) {
                out_ << " [@" << f->pipeline_stage;

                if (f->workgroup_size) {
                    auto arr = f->workgroup_size.value();
                    out_ << " @workgroup_size(" << arr[0] << ", " << arr[1] << ", " << arr[2]
                         << ")";
                }

                if (!f->return_attributes.IsEmpty()) {
                    out_ << " ra:";

                    for (auto attr : f->return_attributes) {
                        out_ << " @" << attr;
                        if (attr == Function::ReturnAttribute::kLocation) {
                            out_ << "(" << f->return_location.value() << ")";
                        }
                    }
                }

                out_ << "]";
            }
            out_ << std::endl;

            {
                ScopedIndent func_indent(&indent_size_);
                ScopedStopNode scope(&stop_nodes_, f->end_target);
                Walk(f->start_target);
            }
            Walk(f->end_target);
        },
        [&](const ir::Block* b) {
            // If this block is dead, nothing to do
            if (b->IsDead()) {
                return;
            }

            Indent() << "%fn" << GetIdForNode(b) << " = block" << std::endl;
            EmitBlockInstructions(b);

            if (b->branch.target->Is<FunctionTerminator>()) {
                Indent() << "ret";
            } else if (b->branch.target->Is<RootTerminator>()) {
                // Nothing to do
            } else {
                Indent() << "branch "
                         << "%fn" << GetIdForNode(b->branch.target);
            }
            if (!b->branch.args.IsEmpty()) {
                out_ << " ";
                for (const auto* v : b->branch.args) {
                    if (v != b->branch.args.Front()) {
                        out_ << ", ";
                    }
                    EmitValue(v);
                }
            }
            out_ << std::endl;

            if (!b->branch.target->Is<FunctionTerminator>()) {
                out_ << std::endl;
            }

            Walk(b->branch.target);
        },
        [&](const ir::Switch* s) {
            Indent() << "%fn" << GetIdForNode(s) << " = switch ";
            EmitValue(s->condition);
            out_ << " [";
            for (const auto& c : s->cases) {
                if (&c != &s->cases.Front()) {
                    out_ << ", ";
                }
                out_ << "c: (";
                for (const auto& selector : c.selectors) {
                    if (&selector != &c.selectors.Front()) {
                        out_ << " ";
                    }

                    if (selector.IsDefault()) {
                        out_ << "default";
                    } else {
                        EmitValue(selector.val);
                    }
                }
                out_ << ", %fn" << GetIdForNode(c.start.target) << ")";
            }
            if (s->merge.target->IsConnected()) {
                out_ << ", m: %fn" << GetIdForNode(s->merge.target);
            }
            out_ << "]" << std::endl;

            {
                ScopedIndent switch_indent(&indent_size_);
                ScopedStopNode scope(&stop_nodes_, s->merge.target);
                for (const auto& c : s->cases) {
                    Indent() << "# case ";
                    for (const auto& selector : c.selectors) {
                        if (&selector != &c.selectors.Front()) {
                            out_ << " ";
                        }

                        if (selector.IsDefault()) {
                            out_ << "default";
                        } else {
                            EmitValue(selector.val);
                        }
                    }
                    out_ << std::endl;
                    Walk(c.start.target);
                }
            }

            if (s->merge.target->IsConnected()) {
                Indent() << "# switch merge" << std::endl;
                Walk(s->merge.target);
            }
        },
        [&](const ir::If* i) {
            Indent() << "%fn" << GetIdForNode(i) << " = if ";
            EmitValue(i->condition);
            out_ << " [t: %fn" << GetIdForNode(i->true_.target) << ", f: %fn"
                 << GetIdForNode(i->false_.target);
            if (i->merge.target->IsConnected()) {
                out_ << ", m: %fn" << GetIdForNode(i->merge.target);
            }
            out_ << "]" << std::endl;

            {
                ScopedIndent if_indent(&indent_size_);
                ScopedStopNode scope(&stop_nodes_, i->merge.target);

                Indent() << "# true branch" << std::endl;
                Walk(i->true_.target);

                if (!i->false_.target->IsDead()) {
                    Indent() << "# false branch" << std::endl;
                    Walk(i->false_.target);
                }
            }

            if (i->merge.target->IsConnected()) {
                Indent() << "# if merge" << std::endl;
                Walk(i->merge.target);
            }
        },
        [&](const ir::Loop* l) {
            Indent() << "%fn" << GetIdForNode(l) << " = loop [s: %fn"
                     << GetIdForNode(l->start.target);

            if (l->continuing.target->IsConnected()) {
                out_ << ", c: %fn" << GetIdForNode(l->continuing.target);
            }
            if (l->merge.target->IsConnected()) {
                out_ << ", m: %fn" << GetIdForNode(l->merge.target);
            }
            out_ << "]" << std::endl;

            {
                ScopedStopNode loop_scope(&stop_nodes_, l->merge.target);
                ScopedIndent loop_indent(&indent_size_);
                {
                    ScopedStopNode inner_scope(&stop_nodes_, l->continuing.target);
                    Indent() << "# loop start" << std::endl;
                    Walk(l->start.target);
                }

                if (l->continuing.target->IsConnected()) {
                    Indent() << "# loop continuing" << std::endl;
                    Walk(l->continuing.target);
                }
            }

            if (l->merge.target->IsConnected()) {
                Indent() << "# loop merge" << std::endl;
                Walk(l->merge.target);
            }
        },
        [&](const ir::FunctionTerminator*) {
            TINT_ASSERT(IR, in_function_);
            Indent() << "func_end" << std::endl << std::endl;
        },
        [&](const ir::RootTerminator*) {
            TINT_ASSERT(IR, !in_function_);
            out_ << std::endl;
        });
}

std::string Disassembler::Disassemble() {
    if (mod_.root_block) {
        Walk(mod_.root_block);
    }

    for (const auto* func : mod_.functions) {
        Walk(func);
    }
    return out_.str();
}

void Disassembler::EmitValue(const Value* val) {
    tint::Switch(
        val,
        [&](const ir::Constant* constant) {
            std::function<void(const constant::Value*)> emit = [&](const constant::Value* c) {
                tint::Switch(
                    c,
                    [&](const constant::Scalar<AFloat>* scalar) {
                        out_ << scalar->ValueAs<AFloat>().value;
                    },
                    [&](const constant::Scalar<AInt>* scalar) {
                        out_ << scalar->ValueAs<AInt>().value;
                    },
                    [&](const constant::Scalar<i32>* scalar) {
                        out_ << scalar->ValueAs<i32>().value << "i";
                    },
                    [&](const constant::Scalar<u32>* scalar) {
                        out_ << scalar->ValueAs<u32>().value << "u";
                    },
                    [&](const constant::Scalar<f32>* scalar) {
                        out_ << scalar->ValueAs<f32>().value << "f";
                    },
                    [&](const constant::Scalar<f16>* scalar) {
                        out_ << scalar->ValueAs<f16>().value << "h";
                    },
                    [&](const constant::Scalar<bool>* scalar) {
                        out_ << (scalar->ValueAs<bool>() ? "true" : "false");
                    },
                    [&](const constant::Splat* splat) {
                        out_ << splat->Type()->FriendlyName() << " ";
                        emit(splat->Index(0));
                    },
                    [&](const constant::Composite* composite) {
                        out_ << composite->Type()->FriendlyName() << " ";
                        for (const auto* elem : composite->elements) {
                            if (elem != composite->elements[0]) {
                                out_ << ", ";
                            }
                            emit(elem);
                        }
                    });
            };
            emit(constant->value);
        },
        [&](const ir::Instruction* i) {
            if (i->id == ir::Instruction::kNoID) {
                out_ << "<no-id>";
            } else {
                out_ << "%" << i->id;
            }
            if (i->Type() != nullptr) {
                out_ << ":" << i->Type()->FriendlyName();
            }
        });
}

void Disassembler::EmitInstruction(const Instruction* inst) {
    tint::Switch(
        inst,  //
        [&](const ir::Binary* b) { EmitBinary(b); }, [&](const ir::Unary* u) { EmitUnary(u); },
        [&](const ir::Bitcast* b) {
            EmitValue(b);
            out_ << " = bitcast ";
            EmitArgs(b);
        },
        [&](const ir::Discard*) { out_ << "discard"; },
        [&](const ir::Builtin* b) {
            EmitValue(b);
            out_ << " = " << builtin::str(b->Func()) << " ";
            EmitArgs(b);
        },
        [&](const ir::Construct* c) {
            EmitValue(c);
            out_ << " = construct ";
            EmitArgs(c);
        },
        [&](const ir::Convert* c) {
            EmitValue(c);
            out_ << " = convert " << c->FromType()->FriendlyName() << ", ";
            EmitArgs(c);
        },
        [&](const ir::Store* s) {
            out_ << "store ";
            EmitValue(s->to);
            out_ << ", ";
            EmitValue(s->from);
        },
        [&](const ir::UserCall* uc) {
            EmitValue(uc);
            out_ << " = call " << uc->name.Name();
            if (uc->args.Length() > 0) {
                out_ << ", ";
            }
            EmitArgs(uc);
        },
        [&](const ir::Var* v) {
            EmitValue(v);
            out_ << " = var " << v->address_space << " " << v->access;
        });
}

void Disassembler::EmitArgs(const Call* call) {
    bool first = true;
    for (const auto* arg : call->args) {
        if (!first) {
            out_ << ", ";
        }
        first = false;
        EmitValue(arg);
    }
}

void Disassembler::EmitBinary(const Binary* b) {
    EmitValue(b);
    out_ << " = ";
    switch (b->GetKind()) {
        case Binary::Kind::kAdd:
            out_ << "add";
            break;
        case Binary::Kind::kSubtract:
            out_ << "sub";
            break;
        case Binary::Kind::kMultiply:
            out_ << "mul";
            break;
        case Binary::Kind::kDivide:
            out_ << "div";
            break;
        case Binary::Kind::kModulo:
            out_ << "mod";
            break;
        case Binary::Kind::kAnd:
            out_ << "and";
            break;
        case Binary::Kind::kOr:
            out_ << "or";
            break;
        case Binary::Kind::kXor:
            out_ << "xor";
            break;
        case Binary::Kind::kEqual:
            out_ << "eq";
            break;
        case Binary::Kind::kNotEqual:
            out_ << "neq";
            break;
        case Binary::Kind::kLessThan:
            out_ << "lt";
            break;
        case Binary::Kind::kGreaterThan:
            out_ << "gt";
            break;
        case Binary::Kind::kLessThanEqual:
            out_ << "lte";
            break;
        case Binary::Kind::kGreaterThanEqual:
            out_ << "gte";
            break;
        case Binary::Kind::kShiftLeft:
            out_ << "shiftl";
            break;
        case Binary::Kind::kShiftRight:
            out_ << "shiftr";
            break;
    }
    out_ << " ";
    EmitValue(b->LHS());
    out_ << ", ";
    EmitValue(b->RHS());
}

void Disassembler::EmitUnary(const Unary* u) {
    EmitValue(u);
    out_ << " = ";
    switch (u->GetKind()) {
        case Unary::Kind::kAddressOf:
            out_ << "addr_of";
            break;
        case Unary::Kind::kComplement:
            out_ << "complement";
            break;
        case Unary::Kind::kIndirection:
            out_ << "indirection";
            break;
        case Unary::Kind::kNegation:
            out_ << "negation";
            break;
    }
    out_ << " ";
    EmitValue(u->Val());
}

}  // namespace tint::ir
