#!/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.cros_build_lib
except ImportError:
  lib_location = os.path.join(os.path.dirname(sys.argv[0]), '../../..')
  sys.path.append(lib_location)
  try:
    import chromite.lib.cros_build_lib
  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.
  '''

  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 = []

  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):
    '''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.
             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:
      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:
      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:
    #
    # `* (no branch) <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\) *(?:\x1b..)? *([^ ]+) ', branch)
    if m:
      branch_sha1 = m.groups(0)[0]
      # 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 ShowDir(project, root, color, options, result):
  """Report active work in a single git repository."""

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

  result.ReportStartedThread()

  if not os.path.isdir(full_name):
    print '\r%s does not exist' % full_name
    result.ReportFinishedThread('')
    return

  branches = GetBranches(full_name, color, project['local_revision'])
  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

  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.cros_build_lib.FindRepoDir()
  if repo_path is None:
    repo_path = chromite.lib.cros_build_lib.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.cros_build_lib.Manifest(
    os.path.join(root, '.repo/manifest.xml'))
  projects = manifest.projects

  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()
