// 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/debug.h"

#include <unordered_map>
#include <unordered_set>

#include "src/tint/ir/block.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
#include "src/tint/ir/switch.h"
#include "src/tint/ir/terminator.h"
#include "src/tint/utils/string_stream.h"

namespace tint::ir {

// static
std::string Debug::AsDotGraph(const Module* mod) {
    size_t node_count = 0;

    std::unordered_set<const FlowNode*> visited;
    std::unordered_set<const FlowNode*> merge_nodes;
    std::unordered_map<const FlowNode*, std::string> node_to_name;
    utils::StringStream out;

    auto name_for = [&](const FlowNode* node) -> std::string {
        if (node_to_name.count(node) > 0) {
            return node_to_name[node];
        }

        std::string name = "node_" + std::to_string(node_count);
        node_count += 1;

        node_to_name[node] = name;
        return name;
    };

    std::function<void(const FlowNode*)> Graph = [&](const FlowNode* node) {
        if (visited.count(node) > 0) {
            return;
        }
        visited.insert(node);

        tint::Switch(
            node,
            [&](const ir::Block* b) {
                if (node_to_name.count(b) == 0) {
                    out << name_for(b) << R"( [label="block"])" << std::endl;
                }
                out << name_for(b) << " -> " << name_for(b->branch.target);

                // Dashed lines to merge blocks
                if (merge_nodes.count(b->branch.target) != 0) {
                    out << " [style=dashed]";
                }

                out << std::endl;
                Graph(b->branch.target);
            },
            [&](const ir::Switch* s) {
                out << name_for(s) << R"( [label="switch"])" << std::endl;
                out << name_for(s->merge.target) << R"( [label="switch merge"])" << std::endl;
                merge_nodes.insert(s->merge.target);

                size_t i = 0;
                for (const auto& c : s->cases) {
                    out << name_for(c.start.target)
                        << R"( [label="case )" + std::to_string(i++) + R"("])" << std::endl;
                }
                out << name_for(s) << " -> {";
                for (const auto& c : s->cases) {
                    if (&c != &(s->cases[0])) {
                        out << ", ";
                    }
                    out << name_for(c.start.target);
                }
                out << "}" << std::endl;

                for (const auto& c : s->cases) {
                    Graph(c.start.target);
                }
                Graph(s->merge.target);
            },
            [&](const ir::If* i) {
                out << name_for(i) << R"( [label="if"])" << std::endl;
                out << name_for(i->true_.target) << R"( [label="true"])" << std::endl;
                out << name_for(i->false_.target) << R"( [label="false"])" << std::endl;
                out << name_for(i->merge.target) << R"( [label="if merge"])" << std::endl;
                merge_nodes.insert(i->merge.target);

                out << name_for(i) << " -> {";
                out << name_for(i->true_.target) << ", " << name_for(i->false_.target);
                out << "}" << std::endl;

                // Subgraph if true/false branches so they draw on the same line
                out << "subgraph sub_" << name_for(i) << " {" << std::endl;
                out << R"(rank="same")" << std::endl;
                out << name_for(i->true_.target) << std::endl;
                out << name_for(i->false_.target) << std::endl;
                out << "}" << std::endl;

                Graph(i->true_.target);
                Graph(i->false_.target);
                Graph(i->merge.target);
            },
            [&](const ir::Loop* l) {
                out << name_for(l) << R"( [label="loop"])" << std::endl;
                out << name_for(l->start.target) << R"( [label="start"])" << std::endl;
                out << name_for(l->continuing.target) << R"( [label="continuing"])" << std::endl;
                out << name_for(l->merge.target) << R"( [label="loop merge"])" << std::endl;
                merge_nodes.insert(l->merge.target);

                // Subgraph the continuing and merge so they get drawn on the same line
                out << "subgraph sub_" << name_for(l) << " {" << std::endl;
                out << R"(rank="same")" << std::endl;
                out << name_for(l->continuing.target) << std::endl;
                out << name_for(l->merge.target) << std::endl;
                out << "}" << std::endl;

                out << name_for(l) << " -> " << name_for(l->start.target) << std::endl;

                Graph(l->start.target);
                Graph(l->continuing.target);
                Graph(l->merge.target);
            },
            [&](const ir::Terminator*) {
                // Already done
            });
    };

    out << "digraph G {" << std::endl;
    for (const auto* func : mod->functions) {
        // Cluster each function to label and draw a box around it.
        out << "subgraph cluster_" << name_for(func) << " {" << std::endl;
        out << R"(label=")" << mod->symbols.NameFor(func->name) << R"(")" << std::endl;
        out << name_for(func->start_target) << R"( [label="start"])" << std::endl;
        out << name_for(func->end_target) << R"( [label="end"])" << std::endl;
        Graph(func->start_target);
        out << "}" << std::endl;
    }
    out << "}";
    return out.str();
}

}  // namespace tint::ir
