#!/usr/bin/env python
# Copyright 2014 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.

"""Print dependency tree of branches in local repo.

Example:
origin/main
  cool_feature
    dependent_feature
    other_dependent_feature
  other_feature

Branches are colorized as follows:
  * Red - a remote branch (usually the root of all local branches)
  * Cyan - a local branch which is the same as HEAD
    * Note that multiple branches may be Cyan, if they are all on the same
      commit, and you have that commit checked out.
  * Green - a local branch
  * Blue - a 'branch-heads' branch
  * Magenta - a tag
  * Magenta '{NO UPSTREAM}' - If you have local branches which do not track any
    upstream, then you will see this.
"""

from __future__ import print_function

import argparse
import collections
import os
import subprocess2
import sys

from git_common import current_branch, upstream, tags, get_branches_info
from git_common import get_git_version, MIN_UPSTREAM_TRACK_GIT_VERSION, hash_one
from git_common import run

import setup_color

from third_party.colorama import Fore, Style

DEFAULT_SEPARATOR = ' ' * 4


class OutputManager(object):
  """Manages a number of OutputLines and formats them into aligned columns."""

  def __init__(self):
    self.lines = []
    self.nocolor = False
    self.max_column_lengths = []
    self.num_columns = None

  def append(self, line):
    # All lines must have the same number of columns.
    if not self.num_columns:
      self.num_columns = len(line.columns)
      self.max_column_lengths = [0] * self.num_columns
    assert self.num_columns == len(line.columns)

    if self.nocolor:
      line.colors = [''] * self.num_columns

    self.lines.append(line)

    # Update maximum column lengths.
    for i, col in enumerate(line.columns):
      self.max_column_lengths[i] = max(self.max_column_lengths[i], len(col))

  def as_formatted_string(self):
    return '\n'.join(
        l.as_padded_string(self.max_column_lengths) for l in self.lines)


class OutputLine(object):
  """A single line of data.

  This consists of an equal number of columns, colors and separators."""

  def __init__(self):
    self.columns = []
    self.separators = []
    self.colors = []

  def append(self, data, separator=DEFAULT_SEPARATOR, color=Fore.WHITE):
    self.columns.append(data)
    self.separators.append(separator)
    self.colors.append(color)

  def as_padded_string(self, max_column_lengths):
    """"Returns the data as a string with each column padded to
    |max_column_lengths|."""
    output_string = ''
    for i, (color, data, separator) in enumerate(
        zip(self.colors, self.columns, self.separators)):
      if max_column_lengths[i] == 0:
        continue

      padding = (max_column_lengths[i] - len(data)) * ' '
      output_string += color + data + padding + separator

    return output_string.rstrip()


class BranchMapper(object):
  """A class which constructs output representing the tree's branch structure.

  Attributes:
    __branches_info: a map of branches to their BranchesInfo objects which
      consist of the branch hash, upstream and ahead/behind status.
    __gone_branches: a set of upstreams which are not fetchable by git"""

  def __init__(self):
    self.verbosity = 0
    self.maxjobs = 0
    self.show_subject = False
    self.output = OutputManager()
    self.__gone_branches = set()
    self.__branches_info = None
    self.__parent_map = collections.defaultdict(list)
    self.__current_branch = None
    self.__current_hash = None
    self.__tag_set = None
    self.__status_info = {}

  def start(self):
    self.__branches_info = get_branches_info(
        include_tracking_status=self.verbosity >= 1)
    if (self.verbosity >= 2):
      # Avoid heavy import unless necessary.
      from git_cl import get_cl_statuses, color_for_status, Changelist

      change_cls = [Changelist(branchref='refs/heads/'+b)
                    for b in self.__branches_info.keys() if b]
      status_info = get_cl_statuses(change_cls,
                                    fine_grained=self.verbosity > 2,
                                    max_processes=self.maxjobs)

      # This is a blocking get which waits for the remote CL status to be
      # retrieved.
      for cl, status in status_info:
        self.__status_info[cl.GetBranch()] = (cl.GetIssueURL(short=True),
                                              color_for_status(status), status)

    roots = set()

    # A map of parents to a list of their children.
    for branch, branch_info in self.__branches_info.items():
      if not branch_info:
        continue

      parent = branch_info.upstream
      if self.__check_cycle(branch):
        continue
      if not self.__branches_info[parent]:
        branch_upstream = upstream(branch)
        # If git can't find the upstream, mark the upstream as gone.
        if branch_upstream:
          parent = branch_upstream
        else:
          self.__gone_branches.add(parent)
        # A parent that isn't in the branches info is a root.
        roots.add(parent)

      self.__parent_map[parent].append(branch)

    self.__current_branch = current_branch()
    self.__current_hash = hash_one('HEAD', short=True)
    self.__tag_set = tags()

    if roots:
      for root in sorted(roots):
        self.__append_branch(root)
    else:
      no_branches = OutputLine()
      no_branches.append('No User Branches')
      self.output.append(no_branches)

  def __check_cycle(self, branch):
    # Maximum length of the cycle is `num_branches`. This limit avoids running
    # into a cycle which does *not* contain `branch`.
    num_branches = len(self.__branches_info)
    cycle = [branch]
    while len(cycle) < num_branches and self.__branches_info[cycle[-1]]:
      parent = self.__branches_info[cycle[-1]].upstream
      cycle.append(parent)
      if parent == branch:
        print('Warning: Detected cycle in branches: {}'.format(
            ' -> '.join(cycle)), file=sys.stderr)
        return True
    return False

  def __is_invalid_parent(self, parent):
    return not parent or parent in self.__gone_branches

  def __color_for_branch(self, branch, branch_hash):
    if branch.startswith('origin/'):
      color = Fore.RED
    elif branch.startswith('branch-heads'):
      color = Fore.BLUE
    elif self.__is_invalid_parent(branch) or branch in self.__tag_set:
      color = Fore.MAGENTA
    elif self.__current_hash.startswith(branch_hash):
      color = Fore.CYAN
    else:
      color = Fore.GREEN

    if branch_hash and self.__current_hash.startswith(branch_hash):
      color += Style.BRIGHT
    else:
      color += Style.NORMAL

    return color

  def __append_branch(self, branch, depth=0):
    """Recurses through the tree structure and appends an OutputLine to the
    OutputManager for each branch."""
    branch_info = self.__branches_info[branch]
    if branch_info:
      branch_hash = branch_info.hash
    else:
      try:
        branch_hash = hash_one(branch, short=True)
      except subprocess2.CalledProcessError:
        branch_hash = None

    line = OutputLine()

    # The branch name with appropriate indentation.
    suffix = ''
    if branch == self.__current_branch or (
        self.__current_branch == 'HEAD' and branch == self.__current_hash):
      suffix = ' *'
    branch_string = branch
    if branch in self.__gone_branches:
      branch_string = '{%s:GONE}' % branch
    if not branch:
      branch_string = '{NO_UPSTREAM}'
    main_string = '  ' * depth + branch_string + suffix
    line.append(
        main_string,
        color=self.__color_for_branch(branch, branch_hash))

    # The branch hash.
    if self.verbosity >= 2:
      line.append(branch_hash or '', separator=' ', color=Fore.RED)

    # The branch tracking status.
    if self.verbosity >= 1:
      commits_string = ''
      behind_string = ''
      front_separator = ''
      center_separator = ''
      back_separator = ''
      if branch_info and not self.__is_invalid_parent(branch_info.upstream):
        behind = branch_info.behind
        commits = branch_info.commits

        if commits:
          commits_string = '%d commit' % commits
          commits_string += 's' if commits > 1 else ' '
        if behind:
          behind_string = 'behind %d' % behind

        if commits or behind:
          front_separator = '['
          back_separator = ']'

        if commits and behind:
          center_separator = '|'

      line.append(front_separator, separator=' ')
      line.append(commits_string, separator=' ', color=Fore.MAGENTA)
      line.append(center_separator, separator=' ')
      line.append(behind_string, separator=' ', color=Fore.MAGENTA)
      line.append(back_separator)

    # The Rietveld issue associated with the branch.
    if self.verbosity >= 2:
      (url, color, status) = ('', '', '') if self.__is_invalid_parent(branch) \
          else self.__status_info[branch]
      if self.verbosity > 2:
        line.append('{} ({})'.format(url, status) if url else '', color=color)
      else:
        line.append(url or '', color=color)

    # The subject of the most recent commit on the branch.
    if self.show_subject:
      if branch:
        line.append(run('log', '-n1', '--format=%s', branch, '--'))
      else:
        line.append('')

    self.output.append(line)

    for child in sorted(self.__parent_map.pop(branch, ())):
      self.__append_branch(child, depth=depth + 1)


def print_desc():
  for line in __doc__.splitlines():
    starpos = line.find('* ')
    if starpos == -1 or '-' not in line:
      print(line)
    else:
      _, color, rest = line.split(None, 2)
      outline = line[:starpos+1]
      outline += getattr(Fore, color.upper()) + " " + color + " " + Fore.RESET
      outline += rest
      print(outline)
  print('')

def main(argv):
  setup_color.init()
  if get_git_version() < MIN_UPSTREAM_TRACK_GIT_VERSION:
    print(
        'This tool will not show all tracking information for git version '
        'earlier than ' +
        '.'.join(str(x) for x in MIN_UPSTREAM_TRACK_GIT_VERSION) +
        '. Please consider upgrading.', file=sys.stderr)

  if '-h' in argv:
    print_desc()

  parser = argparse.ArgumentParser()
  parser.add_argument('-v', action='count', default=0,
                      help=('Pass once to show tracking info, '
                            'twice for hash and review url, '
                            'thrice for review status'))
  parser.add_argument('--no-color', action='store_true', dest='nocolor',
                      help='Turn off colors.')
  parser.add_argument(
      '-j', '--maxjobs', action='store', type=int,
      help='The number of jobs to use when retrieving review status')
  parser.add_argument('--show-subject', action='store_true',
                      dest='show_subject', help='Show the commit subject.')

  opts = parser.parse_args(argv)

  mapper = BranchMapper()
  mapper.verbosity = opts.v
  mapper.output.nocolor = opts.nocolor
  mapper.maxjobs = opts.maxjobs
  mapper.show_subject = opts.show_subject
  mapper.start()
  print(mapper.output.as_formatted_string())
  return 0

if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except KeyboardInterrupt:
    sys.stderr.write('interrupted\n')
    sys.exit(1)
