#!/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), end=' ')

  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), end=' ')
      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.run(command,
      cwd=path, stdout=subprocess.PIPE, encoding='utf-8').stdout.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>'
    # For versions older than git 2.4.x:
    # `* (detached from <sha_1>) <sha_1> <description>'
    # Newer versions:
    # `* (HEAD detached from <sha_1>) <sha_1> <description>'
    # `* (HEAD detached at <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|(?:HEAD )?detached (?:at|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):
      if chromite.lib.git.IsSHA1(project['revision']):
        top_revision = project['revision']
      else:
        top_revision = project['tracking_branch']
      text = ShowBranches(full_name, top_revision, 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 = manifest.ListCheckouts()

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

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

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


if __name__ == '__main__':
  main()
