#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Dumps a graph of allowed and disallowed inter-module dependencies described
by the DEPS files in the source tree. Supports DOT and PNG as the output format.

Enables filtering and differential highlighting of parts of the graph based on
the specified criteria. This allows for a much easier visual analysis of the
dependencies, including answering questions such as "if a new source must
depend on modules A, B, and C, what valid options among the existing modules
are there to put it in."

See builddeps.py for a detailed description of the DEPS format.
"""

import os
import optparse
import pipes
import re
import sys

from builddeps import DepsBuilder
from rules import Rule


class DepsGrapher(DepsBuilder):
  """Parses include_rules from DEPS files and outputs a DOT graph of the
  allowed and disallowed dependencies between directories and specific file
  regexps. Can generate only a subgraph of the whole dependency graph
  corresponding to the provided inclusion and exclusion regexp filters.
  Also can highlight fanins and/or fanouts of certain nodes matching the
  provided regexp patterns.
  """

  def __init__(self,
               base_directory,
               verbose,
               being_tested,
               ignore_temp_rules,
               ignore_specific_rules,
               hide_disallowed_deps,
               out_file,
               out_format,
               layout_engine,
               unflatten_graph,
               incl,
               excl,
               hilite_fanins,
               hilite_fanouts):
    """Creates a new DepsGrapher.

    Args:
      base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src.
      verbose: Set to true for debug output.
      being_tested: Set to true to ignore the DEPS file at tools/graphdeps/DEPS.
      ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!").
      ignore_specific_rules: Ignore rules from specific_include_rules sections.
      hide_disallowed_deps: Hide disallowed dependencies from the output graph.
      out_file: Output file name.
      out_format: Output format (anything GraphViz dot's -T option supports).
      layout_engine: Layout engine for formats other than 'dot'
                     (anything that GraphViz dot's -K option supports).
      unflatten_graph: Try to reformat the output graph so it is narrower and
                       taller. Helps fight overly flat and wide graphs, but
                       sometimes produces a worse result.
      incl: Include only nodes matching this regexp; such nodes' fanin/fanout
            is also included.
      excl: Exclude nodes matching this regexp; such nodes' fanin/fanout is
            processed independently.
      hilite_fanins: Highlight fanins of nodes matching this regexp with a
                     different edge and node color.
      hilite_fanouts: Highlight fanouts of nodes matching this regexp with a
                      different edge and node color.
    """
    DepsBuilder.__init__(
        self,
        base_directory,
        verbose,
        being_tested,
        ignore_temp_rules,
        ignore_specific_rules)

    self.ignore_temp_rules = ignore_temp_rules
    self.ignore_specific_rules = ignore_specific_rules
    self.hide_disallowed_deps = hide_disallowed_deps
    self.out_file = out_file
    self.out_format = out_format
    self.layout_engine = layout_engine
    self.unflatten_graph = unflatten_graph
    self.incl = incl
    self.excl = excl
    self.hilite_fanins = hilite_fanins
    self.hilite_fanouts = hilite_fanouts

    self.deps = set()

  def DumpDependencies(self):
    """ Builds a dependency rule table and dumps the corresponding dependency
    graph to all requested formats."""
    self._BuildDepsGraph(self.base_directory)
    self._DumpDependencies()

  def _BuildDepsGraph(self, full_path):
    """Recursively traverses the source tree starting at the specified directory
    and builds a dependency graph representation in self.deps."""
    rel_path = os.path.relpath(full_path, self.base_directory)
    #if re.search(self.incl, rel_path) and not re.search(self.excl, rel_path):
    rules = self.GetDirectoryRules(full_path)
    if rules:
      deps = rules.AsDependencyTuples(
          include_general_rules=True,
          include_specific_rules=not self.ignore_specific_rules)
      self.deps.update(deps)

    for item in os.listdir(full_path):
      next_full_path = os.path.join(full_path, item)
      if os.path.isdir(next_full_path):
        self._BuildDepsGraph(next_full_path)

  def _DumpDependencies(self):
    """Dumps the built dependency graph to the specified file with specified
    format."""
    if self.out_format == 'dot' and not self.layout_engine:
      if self.unflatten_graph:
        pipe = pipes.Template()
        pipe.append('unflatten -l 2 -c 3', '--')
        out = pipe.open(self.out_file, 'w')
      else:
        out = open(self.out_file, 'w')
    else:
      pipe = pipes.Template()
      if self.unflatten_graph:
        pipe.append('unflatten -l 2 -c 3', '--')
      dot_cmd = 'dot -T' + self.out_format
      if self.layout_engine:
        dot_cmd += ' -K' + self.layout_engine
      pipe.append(dot_cmd, '--')
      out = pipe.open(self.out_file, 'w')

    self._DumpDependenciesImpl(self.deps, out)
    out.close()

  def _DumpDependenciesImpl(self, deps, out):
    """Computes nodes' and edges' properties for the dependency graph |deps| and
    carries out the actual dumping to a file/pipe |out|."""
    deps_graph = dict()
    deps_srcs = set()

    # Pre-initialize the graph with src->(dst, allow) pairs.
    for (allow, src, dst) in deps:
      if allow == Rule.TEMP_ALLOW and self.ignore_temp_rules:
        continue

      deps_srcs.add(src)
      if src not in deps_graph:
        deps_graph[src] = []
      deps_graph[src].append((dst, allow))

      # Add all hierarchical parents too, in case some of them don't have their
      # own DEPS, and therefore are missing from the list of rules. Those will
      # be recursively populated with their parents' rules in the next block.
      parent_src = os.path.dirname(src)
      while parent_src:
        if parent_src not in deps_graph:
          deps_graph[parent_src] = []
        parent_src = os.path.dirname(parent_src)

    # For every node, propagate its rules down to all its children.
    deps_srcs = list(deps_srcs)
    deps_srcs.sort()
    for src in deps_srcs:
      parent_src = os.path.dirname(src)
      if parent_src:
        # We presort the list, so parents are guaranteed to precede children.
        assert parent_src in deps_graph,\
               "src: %s, parent_src: %s" % (src, parent_src)
        for (dst, allow) in deps_graph[parent_src]:
          # Check that this node does not explicitly override a rule from the
          # parent that we're about to add.
          if ((dst, Rule.ALLOW) not in deps_graph[src]) and \
             ((dst, Rule.TEMP_ALLOW) not in deps_graph[src]) and \
             ((dst, Rule.DISALLOW) not in deps_graph[src]):
            deps_graph[src].append((dst, allow))

    node_props = {}
    edges = []

    # 1) Populate a list of edge specifications in DOT format;
    # 2) Populate a list of computed raw node attributes to be output as node
    #    specifications in DOT format later on.
    # Edges and nodes are emphasized with color and line/border weight depending
    # on how many of incl/excl/hilite_fanins/hilite_fanouts filters they hit,
    # and in what way.
    for src in deps_graph.keys():
      for (dst, allow) in deps_graph[src]:
        if allow == Rule.DISALLOW and self.hide_disallowed_deps:
          continue

        if allow == Rule.ALLOW and src == dst:
          continue

        edge_spec = "%s->%s" % (src, dst)
        if not re.search(self.incl, edge_spec) or \
               re.search(self.excl, edge_spec):
          continue

        if src not in node_props:
          node_props[src] = {'hilite': None, 'degree': 0}
        if dst not in node_props:
          node_props[dst] = {'hilite': None, 'degree': 0}

        edge_weight = 1

        if self.hilite_fanouts and re.search(self.hilite_fanouts, src):
          node_props[src]['hilite'] = 'lightgreen'
          node_props[dst]['hilite'] = 'lightblue'
          node_props[dst]['degree'] += 1
          edge_weight += 1

        if self.hilite_fanins and re.search(self.hilite_fanins, dst):
          node_props[src]['hilite'] = 'lightblue'
          node_props[dst]['hilite'] = 'lightgreen'
          node_props[src]['degree'] += 1
          edge_weight += 1

        if allow == Rule.ALLOW:
          edge_color = (edge_weight > 1) and 'blue' or 'green'
          edge_style = 'solid'
        elif allow == Rule.TEMP_ALLOW:
          edge_color = (edge_weight > 1) and 'blue' or 'green'
          edge_style = 'dashed'
        else:
          edge_color = 'red'
          edge_style = 'dashed'
        edges.append('    "%s" -> "%s" [style=%s,color=%s,penwidth=%d];' % \
            (src, dst, edge_style, edge_color, edge_weight))

    # Reformat the computed raw node attributes into a final DOT representation.
    nodes = []
    for (node, attrs) in node_props.iteritems():
      attr_strs = []
      if attrs['hilite']:
        attr_strs.append('style=filled,fillcolor=%s' % attrs['hilite'])
      attr_strs.append('penwidth=%d' % (attrs['degree'] or 1))
      nodes.append('    "%s" [%s];' % (node, ','.join(attr_strs)))

    # Output nodes and edges to |out| (can be a file or a pipe).
    edges.sort()
    nodes.sort()
    out.write('digraph DEPS {\n'
              '    fontsize=8;\n')
    out.write('\n'.join(nodes))
    out.write('\n\n')
    out.write('\n'.join(edges))
    out.write('\n}\n')
    out.close()


def PrintUsage():
  print """Usage: python graphdeps.py [--root <root>]

  --root ROOT Specifies the repository root. This defaults to "../../.."
              relative to the script file. This will be correct given the
              normal location of the script in "<root>/tools/graphdeps".

  --(others)  There are a few lesser-used options; run with --help to show them.

Examples:
  Dump the whole dependency graph:
    graphdeps.py
  Find a suitable place for a new source that must depend on /apps and
  /content/browser/renderer_host. Limit potential candidates to /apps,
  /chrome/browser and content/browser, and descendants of those three.
  Generate both DOT and PNG output. The output will highlight the fanins
  of /apps and /content/browser/renderer_host. Overlapping nodes in both fanins
  will be emphasized by a thicker border. Those nodes are the ones that are
  allowed to depend on both targets, therefore they are all legal candidates
  to place the new source in:
    graphdeps.py \
      --root=./src \
      --out=./DEPS.svg \
      --format=svg \
      --incl='^(apps|chrome/browser|content/browser)->.*' \
      --excl='.*->third_party' \
      --fanin='^(apps|content/browser/renderer_host)$' \
      --ignore-specific-rules \
      --ignore-temp-rules"""


def main():
  option_parser = optparse.OptionParser()
  option_parser.add_option(
      "", "--root",
      default="", dest="base_directory",
      help="Specifies the repository root. This defaults "
           "to '../../..' relative to the script file, which "
           "will normally be the repository root.")
  option_parser.add_option(
      "-f", "--format",
      dest="out_format", default="dot",
      help="Output file format. "
           "Can be anything that GraphViz dot's -T option supports. "
           "The most useful ones are: dot (text), svg (image), pdf (image)."
           "NOTES: dotty has a known problem with fonts when displaying DOT "
           "files on Ubuntu - if labels are unreadable, try other formats.")
  option_parser.add_option(
      "-o", "--out",
      dest="out_file", default="DEPS",
      help="Output file name. If the name does not end in an extension "
           "matching the output format, that extension is automatically "
           "appended.")
  option_parser.add_option(
      "-l", "--layout-engine",
      dest="layout_engine", default="",
      help="Layout rendering engine. "
           "Can be anything that GraphViz dot's -K option supports. "
           "The most useful are in decreasing order: dot, fdp, circo, osage. "
           "NOTE: '-f dot' and '-f dot -l dot' are different: the former "
           "will dump a raw DOT graph and stop; the latter will further "
           "filter it through 'dot -Tdot -Kdot' layout engine.")
  option_parser.add_option(
      "-i", "--incl",
      default="^.*$", dest="incl",
      help="Include only edges of the graph that match the specified regexp. "
           "The regexp is applied to edges of the graph formatted as "
           "'source_node->target_node', where the '->' part is vebatim. "
           "Therefore, a reliable regexp should look like "
           "'^(chrome|chrome/browser|chrome/common)->content/public/browser$' "
           "or similar, with both source and target node regexps present, "
           "explicit ^ and $, and otherwise being as specific as possible.")
  option_parser.add_option(
      "-e", "--excl",
      default="^$", dest="excl",
      help="Exclude dependent nodes that match the specified regexp. "
           "See --incl for details on the format.")
  option_parser.add_option(
      "", "--fanin",
      default="", dest="hilite_fanins",
      help="Highlight fanins of nodes matching the specified regexp.")
  option_parser.add_option(
      "", "--fanout",
      default="", dest="hilite_fanouts",
      help="Highlight fanouts of nodes matching the specified regexp.")
  option_parser.add_option(
      "", "--ignore-temp-rules",
      action="store_true", dest="ignore_temp_rules", default=False,
      help="Ignore !-prefixed (temporary) rules in DEPS files.")
  option_parser.add_option(
      "", "--ignore-specific-rules",
      action="store_true", dest="ignore_specific_rules", default=False,
      help="Ignore specific_include_rules section of DEPS files.")
  option_parser.add_option(
      "", "--hide-disallowed-deps",
      action="store_true", dest="hide_disallowed_deps", default=False,
      help="Hide disallowed dependencies in the output graph.")
  option_parser.add_option(
      "", "--unflatten",
      action="store_true", dest="unflatten_graph", default=False,
      help="Try to reformat the output graph so it is narrower and taller. "
           "Helps fight overly flat and wide graphs, but sometimes produces "
           "inferior results.")
  option_parser.add_option(
      "-v", "--verbose",
      action="store_true", default=False,
      help="Print debug logging")
  options, args = option_parser.parse_args()

  if not options.out_file.endswith(options.out_format):
    options.out_file += '.' + options.out_format

  deps_grapher = DepsGrapher(
      base_directory=options.base_directory,
      verbose=options.verbose,
      being_tested=False,

      ignore_temp_rules=options.ignore_temp_rules,
      ignore_specific_rules=options.ignore_specific_rules,
      hide_disallowed_deps=options.hide_disallowed_deps,

      out_file=options.out_file,
      out_format=options.out_format,
      layout_engine=options.layout_engine,
      unflatten_graph=options.unflatten_graph,

      incl=options.incl,
      excl=options.excl,
      hilite_fanins=options.hilite_fanins,
      hilite_fanouts=options.hilite_fanouts)

  if len(args) > 0:
    PrintUsage()
    return 1

  print 'Using base directory: ', deps_grapher.base_directory
  print 'include nodes       : ', options.incl
  print 'exclude nodes       : ', options.excl
  print 'highlight fanins of : ', options.hilite_fanins
  print 'highlight fanouts of: ', options.hilite_fanouts

  deps_grapher.DumpDependencies()
  return 0


if '__main__' == __name__:
  sys.exit(main())
