#!/usr/bin/env python
# Copyright (c) 2011 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.

"""Display active git branches and code changes in a ChromiumOS workspace."""

import optparse
import os
import re
import subprocess
import sys
import threading

try:
  import chromite.lib.git
except ImportError:
  lib_location = os.path.join(os.path.dirname(sys.argv[0]), '../../..')
  sys.path.append(lib_location)
  try:
    import chromite.lib.git
  except ImportError:
    print 'Failed to import chromite library'
    sys.exit(1)

import chromite.lib.terminal

Colorizer = chromite.lib.terminal.Color(os.isatty(sys.stdout.fileno()))

class Result(object):
  '''A class to synchronize multiple repository request threads.

  Multiple parallel running threads collect text information (for instance,
  state of different git repositories, one per thread).

  Using this class object allows these multiple threads to synchronously
  attach collected information to a list.

  This class also provides a facility to unblock the master thread once all
  parallel running threads have finished running.

  To make matters simpler, the number of parallel threads to expect to run is
  given to this class during initialization.

  Attributes:

    thread_lock - a lock object, used as a mutex to control access to the count
                  of running threads

    finished_lock - a lock object, used as a mutex for the master thread. This
                 lock is locked as soon as the first parallel thread starts
                 and stays locked until the last parallel thread finishes.

    thread_count - an integer, number of parallel threads this object will
                 have to handle.

    fast_report - a boolean, if True - report results as they arrive, do not
                 wait for all thread results to arrive and get sorted

    started_threads - an integer, number of threads started so far.

    results - a list of strings, each representing a result of a running
                 parallel thread.

    not_existing - an integer, counter of repos which were not found (most
                   often happens in minilayouts)
  '''

  def __init__(self, max_threads, fast_report=False):
    '''Initialize the object with the number of parallel threads to handle.'''

    self.thread_lock = threading.Lock()
    self.finished_lock = threading.Lock()
    self.finished_lock.acquire()
    self.thread_count = max_threads
    self.fast_report = fast_report
    self.started_threads = 0
    self.results = []
    self.not_existing = 0

  def ReportThreadStatus(self):
    '''Print status line when enabled.

    If enabled, print a line showing numbers of started and still running
    threads. Make sure this line is printed in the same screen position (using
    the ANSI cursor control escape sequence).
    '''

    if self.fast_report:
      return
    print '\n%c[1AStarted threads: %3d, remaining threads: %3d' % (
        27, self.started_threads, self.thread_count),

  def ReportStartedThread(self):
    '''Increment started thread count.

    And report status, if enabled.
    '''

    self.thread_lock.acquire()
    self.started_threads = self.started_threads + 1
    self.ReportThreadStatus()
    self.thread_lock.release()

  def ReportFinishedThread(self, result=None):
    '''Report that a parallel thread finished running.

    Each time a finished thread is reported, decrement the running thread
    count. Once the running thread count reaches zero - unblock the master
    thread lock.

    result - a string, representing the output of the thread, could be empty.
             Set to None for threads started on non-existing repositories
             (happens in minilayouts).
             If not empty - ether add this string to the results attribute or
             print it, if fast reporting is enabled.
    '''

    self.thread_lock.acquire()
    if result == None:
      self.not_existing += 1
    elif result:
      if self.fast_report:
        print result
      else:
        self.results.append(result)
    self.thread_count = self.thread_count - 1
    self.ReportThreadStatus()
    self.thread_lock.release()
    if self.thread_count == 0:
      if not self.fast_report:
        # Erase the status line.
        print '\n%c[1A%c[K%c[1A' % (27, 27, 27),
      self.finished_lock.release()

  def GetResults(self):
    '''Wait till all parallel threads finish and return results.

    This function blocks until all parallel threads finish running. Once they
    do, sort the results[] list and return it.
    '''
    with self.finished_lock:
      if self.not_existing:
        self.results.append(Colorizer.Color(
            Colorizer.RED, '%d repos not found' % self.not_existing))
      return sorted(self.results)


def RunCommand(path, command):
  """Run a command in a given directory, return stdout."""

  return subprocess.Popen(command,
                          cwd=path,
                          stdout=subprocess.PIPE).communicate()[0].rstrip()


def GetBranches(full_name, color, revision):
  """Return a list of branch descriptions."""

  command = ['git', 'branch', '-vv']

  if color:
    command.append('--color')

  branches = RunCommand(full_name, command).splitlines()

  # Find out full sha1 of the tracking branch
  command = ['git', 'rev-parse', revision]
  tracking_sha1 = RunCommand(full_name, command)

  rv = []
  for branch in branches:

    # Let's get the detached HEAD branch sha1. The branch's string looks as
    # follows:
    #
    # For versions older than git 1.8.x:
    # `* (no branch) <sha_1> <description>'
    # Newer versions look like:
    # `* (detached from <sha_1>) <sha_1> <description>'
    #
    # The asterisk could be not there, the '(no branch)' substring could be
    # enveloped in the color enable/disable escape sequences with spaces
    # potentially before and after the escape sequence.
    m = re.search(
        '\*? +[^ ]*\((no branch|detached from [^)]*)\) *(?:\x1b..)? *([^ ]+) ',
        branch)
    if m:
      branch_sha1 = m.groups(0)[1]
      # Does detached HEAD match the tracking branch?
      detached_head_match = tracking_sha1.startswith(branch_sha1)
      if detached_head_match and len(branches) == 1:
        # This is the only local branch in repo, and it matches tracking branch.
        return []
      else:
        if not detached_head_match:
          # Does not match the tracking branch sha1, mark it with a prefix
          rv.append('%s %s' % (Colorizer.Color(Colorizer.RED, '!!!!!'), branch))
          continue

    rv.append(branch)

  return rv

def GetStatus(full_name):
  """Return a list of files that have modifications."""

  command = ['git', 'status', '-s']

  return RunCommand(full_name, command).splitlines()


def GetHistory(full_name, author, days):
  """Return a list of oneline log messages.

  The messages are for the author going back a specified number of days.
  """

  command = ['git', 'log',
             '--author=' + author,
             '--after=' + '-' + str(days) + 'days',
             '--pretty=oneline',
             'm/master']

  return RunCommand(full_name, command).splitlines()


def ShowBranches(full_name, tracking_branch, color, options):
  """Show all local branches' state.

  For a git tree in directory 'full_name' tracking branch named
  'tracking_branch', report the status of the tree.
  """

  branches = GetBranches(full_name, color, tracking_branch)
  status = GetStatus(full_name)

  text = []
  if options.logs:
    history = GetHistory(full_name, options.author, options.days)
  else:
    history = []

  if branches or status or history:
    # We want to use the full path for testing, but we want to use the
    # relative path for display. Add an empty string to the list to have the
    # output sections separated.
    text = [ '', Colorizer.Color(Colorizer.BLUE,
                                 os.path.relpath(full_name)), ]

    for extra in (branches, status, history):
      if extra:
        text = text + extra
  return text


def ShowDir(project, root, color, options, result):
  """Report active work in a single git repository."""

  result.ReportStartedThread()
  text = []

  try:
    full_name = os.path.join(root, project['path'])

    if os.path.isdir(full_name):
      text = ShowBranches(full_name,
                          project['tracking_branch'],
                          color,
                          options)
  except Exception as e:
    text = ['Exception %s occured. Arguments: %s' % (
        type(e).__name__, ' '.join(e.args))]
  result.ReportFinishedThread('\n'.join(text))


def FindRoot():
  """Returns the repo root.

  The script could run both inside and outside chroot. When run outside
  chroot, it could be invoked from the current directory not in chroot source
  tree.

  So, if the search based on the current directory fails, try finding the top
  directory based on the location of this script (presumably it is in the
  chroot source tree).
  """

  # Try looking based on current directory
  repo_path = chromite.lib.git.FindRepoDir(os.getcwd())
  if repo_path is None:
    repo_path = chromite.lib.git.FindRepoDir(os.path.dirname(sys.argv[0]))

  if repo_path is None:
    raise Exception('Failed to find repo root')

  return os.path.dirname(repo_path)


def main():
  parser = optparse.OptionParser(usage = 'usage: %prog [options]\n')

  parser.add_option('-l', '--logs', default=False,
                    help='Show the last few days of your commits in short '
                         'form.',
                    action='store_true',
                    dest='logs')

  parser.add_option('-d', '--days', default=8,
                    help='Set the number of days of history to show.',
                    type='int',
                    dest='days')

  parser.add_option('-a', '--author', default=os.environ['USER'],
                    help='Set the author to filter for.',
                    type='string',
                    dest='author')

  parser.add_option('-f', '--fast-report', default=False,
                    help='Print results as they arrive, do not sort.',
                    action='store_true',
                    dest='fast_report')

  options, arguments = parser.parse_args()

  if arguments:
    parser.print_usage()
    return 1

  color = os.isatty(1)
  root = FindRoot()
  manifest = chromite.lib.git.ManifestCheckout(root)
  projects = {}
  for proj_name, proj_list in manifest.checkouts_by_name.iteritems():
    if len(proj_list) > 1:
      for index in xrange(len(proj_list)):
        projects['%s_%d' % (proj_name, index)] = proj_list[index]
      continue
    projects[proj_name] = proj_list[0]

  result = Result(len(projects), options.fast_report)

  for p in projects.itervalues():
    t = threading.Thread(
        target=ShowDir,
        args=(p, root, color, options, result))
    t.start()

  print '\n'.join(result.GetResults())


if __name__ == '__main__':
  main()
