# Copyright 2010 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Helper functions for building graphs with dot."""

from chromite.lib import cros_build_lib
from chromite.lib import osutils


class Subgraph:
    """A subgraph in dot. Contains nodes, arcs, and other subgraphs."""

    _valid_ranks = {"source", "sink", "same", "min", "max", None}

    def __init__(self, rank=None) -> None:
        self._rank = rank
        self._nodes = []
        self._subgraphs = []
        self._arcs = set()
        self._rank = None

    def AddNode(self, node_id, name=None, color=None, href=None) -> None:
        """Adds a node to the subgraph."""
        tags = {}
        if name:
            tags["label"] = name
        if color:
            tags["color"] = color
            tags["fontcolor"] = color
        if href:
            tags["href"] = href
        self._nodes.append({"id": node_id, "tags": tags})

    def AddSubgraph(self, subgraph) -> None:
        """Adds a subgraph to the subgraph."""
        self._subgraphs.append(subgraph)

    def AddNewSubgraph(self, rank=None):
        """Adds a new subgraph to the subgraph. The new subgraph is returned."""
        subgraph = Subgraph(rank)
        self.AddSubgraph(subgraph)
        return subgraph

    def AddArc(self, node_from, node_to) -> None:
        """Adds an arc between two nodes."""
        self._arcs.add((node_from, node_to))

    def _GenNodes(self):
        """Generates the code for all the nodes."""
        lines = []
        for node in self._nodes:
            tags = ['%s="%s"' % (k, v) for (k, v) in node["tags"].items()]
            lines.append('"%s" [%s];' % (node["id"], ", ".join(tags)))
        return lines

    def _GenSubgraphs(self):
        """Generates the code for all subgraphs contained in this subgraph."""
        lines = []
        for subgraph in self._subgraphs:
            lines += subgraph.Gen()
        return lines

    def _GenArcs(self):
        """Generates the code for all the arcs."""
        lines = []
        for node_from, node_to in self._arcs:
            lines.append('"%s" -> "%s";' % (node_from, node_to))
        return lines

    def _GenInner(self):
        """Generates the code for the inner contents of the subgraph."""
        lines = []
        if self._rank:
            lines.append("rank=%s;" % self._rank)
        lines += self._GenSubgraphs()
        lines += self._GenNodes()
        lines += self._GenArcs()
        return lines

    def Gen(self):
        """Generates the code for the subgraph."""
        return ["subgraph {"] + self._GenInner() + ["}"]


class Graph(Subgraph):
    """A top-level graph in dot. It's basically a subgraph with a name."""

    def __init__(self, name) -> None:
        Subgraph.__init__(self)
        self._name = name

    def Gen(self):
        """Generates the code for the graph."""
        return (
            ['digraph "%s" {' % self._name, 'graph [name="%s"];' % self._name]
            + self._GenInner()
            + ["}"]
        )


def GenerateImage(
    lines, filename, out_format="svg", save_dot_filename=None
) -> None:
    """Generates the image by calling dot on the input lines."""
    data = "\n".join(lines)
    cros_build_lib.run(["dot", "-T%s" % out_format, "-o", filename], input=data)

    if save_dot_filename:
        osutils.WriteFile(save_dot_filename, data)
