# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generates pretty dependency graphs for Chrome OS packages."""

from __future__ import print_function

import json
import optparse  # pylint: disable=deprecated-module
import os
import sys

from chromite.lib import dot_helper


NORMAL_COLOR = 'black'
TARGET_COLOR = 'red'
SEED_COLOR = 'green'
CHILD_COLOR = 'grey'


def GetReverseDependencyClosure(full_name, deps_map):
  """Gets the closure of the reverse dependencies of a node.

  Walks the tree along all the reverse dependency paths to find all the nodes
  that transitively depend on the input node.
  """
  s = set()
  def GetClosure(name):
    s.add(name)
    node = deps_map[name]
    for dep in node['rev_deps']:
      if dep in s:
        continue
      GetClosure(dep)

  GetClosure(full_name)
  return s


def GetOutputBaseName(node, options):
  """Gets the basename of the output file for a node."""
  return '%s_%s-%s.%s' % (node['category'], node['name'], node['version'],
                          options.format)


def AddNodeToSubgraph(subgraph, node, options, color):
  """Gets the dot definition for a node."""
  name = node['full_name']
  href = None
  if options.link:
    filename = GetOutputBaseName(node, options)
    href = '%s%s' % (options.base_url, filename)
  subgraph.AddNode(name, name, color, href)



def GenerateDotGraph(package, deps_map, options):
  """Generates the dot source for the dependency graph leading to a node.

  The output is a list of lines.
  """
  deps = GetReverseDependencyClosure(package, deps_map)
  node = deps_map[package]

  # Keep track of all the emitted nodes so that we don't issue multiple
  # definitions
  emitted = set()

  graph = dot_helper.Graph(package)

  # Add all the children if we want them, all of them in their own subgraph,
  # as a sink. Keep the arcs outside of the subgraph though (it generates
  # better layout).
  children_subgraph = None
  if options.children and node['deps']:
    children_subgraph = graph.AddNewSubgraph('sink')
    for child in node['deps']:
      child_node = deps_map[child]
      AddNodeToSubgraph(children_subgraph, child_node, options, CHILD_COLOR)
      emitted.add(child)
      graph.AddArc(package, child)

  # Add the package in its own subgraph. If we didn't have children, make it
  # a sink
  if children_subgraph:
    rank = 'same'
  else:
    rank = 'sink'
  package_subgraph = graph.AddNewSubgraph(rank)
  AddNodeToSubgraph(package_subgraph, node, options, TARGET_COLOR)
  emitted.add(package)

  # Add all the other nodes, as well as all the arcs.
  for dep in deps:
    dep_node = deps_map[dep]
    if not dep in emitted:
      color = NORMAL_COLOR
      if dep_node['action'] == 'seed':
        color = SEED_COLOR
      AddNodeToSubgraph(graph, dep_node, options, color)
    for j in dep_node['rev_deps']:
      graph.AddArc(j, dep)

  return graph.Gen()


def GenerateImages(data, options):
  """Generate the output images for all the nodes in the input."""
  deps_map = json.loads(data)

  for package in deps_map:
    lines = GenerateDotGraph(package, deps_map, options)

    filename = os.path.join(options.output_dir,
                            GetOutputBaseName(deps_map[package], options))

    save_dot_filename = None
    if options.save_dot:
      save_dot_filename = filename + '.dot'

    dot_helper.GenerateImage(lines, filename, options.format, save_dot_filename)


def main(argv):
  parser = optparse.OptionParser(usage='usage: %prog [options] input')
  parser.add_option('-f', '--format', default='svg',
                    help='Dot output format (png, svg, etc.).')
  parser.add_option('-o', '--output-dir', default='.',
                    help='Output directory.')
  parser.add_option('-c', '--children', action='store_true',
                    help='Also add children.')
  parser.add_option('-l', '--link', action='store_true',
                    help='Embed links.')
  parser.add_option('-b', '--base-url', default='',
                    help='Base url for links.')
  parser.add_option('-s', '--save-dot', action='store_true',
                    help='Save dot files.')
  (options, inputs) = parser.parse_args(argv)

  try:
    os.makedirs(options.output_dir)
  except OSError:
    # The directory already exists.
    pass

  if not inputs:
    GenerateImages(sys.stdin.read(), options)
  else:
    for i in inputs:
      with open(i) as handle:
        GenerateImages(handle.read(), options)
