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

"""Wrapper around git blame that ignores certain commits.
"""

from __future__ import print_function

import argparse
import collections
import logging
import os
import subprocess2
import sys

import git_common
import git_dates
import setup_color


logging.getLogger().setLevel(logging.INFO)


DEFAULT_IGNORE_FILE_NAME = '.git-blame-ignore-revs'


class Commit(object):
  """Info about a commit."""
  def __init__(self, commithash):
    self.commithash = commithash
    self.author = None
    self.author_mail = None
    self.author_time = None
    self.author_tz = None
    self.committer = None
    self.committer_mail = None
    self.committer_time = None
    self.committer_tz = None
    self.summary = None
    self.boundary = None
    self.previous = None
    self.filename = None

  def __repr__(self):  # pragma: no cover
    return '<Commit %s>' % self.commithash


BlameLine = collections.namedtuple(
    'BlameLine',
    'commit context lineno_then lineno_now modified')


def parse_blame(blameoutput):
  """Parses the output of git blame -p into a data structure."""
  lines = blameoutput.split('\n')
  i = 0
  commits = {}

  while i < len(lines):
    # Read a commit line and parse it.
    line = lines[i]
    i += 1
    if not line.strip():
      continue
    commitline = line.split()
    commithash = commitline[0]
    lineno_then = int(commitline[1])
    lineno_now = int(commitline[2])

    try:
      commit = commits[commithash]
    except KeyError:
      commit = Commit(commithash)
      commits[commithash] = commit

    # Read commit details until we find a context line.
    while i < len(lines):
      line = lines[i]
      i += 1
      if line.startswith('\t'):
        break

      try:
        key, value = line.split(' ', 1)
      except ValueError:
        key = line
        value = True
      setattr(commit, key.replace('-', '_'), value)

    context = line[1:]

    yield BlameLine(commit, context, lineno_then, lineno_now, False)


def num_codepoints(s):
  """Gets the length of a UTF-8 byte string, in Unicode codepoints."""
  return len(s.decode('utf-8', errors='replace'))


def print_table(table, colsep=' ', rowsep='\n', align=None, out=sys.stdout):
  """Print a 2D rectangular array, aligning columns with spaces.

  Args:
    align: Optional string of 'l' and 'r', designating whether each column is
           left- or right-aligned. Defaults to left aligned.
  """
  if len(table) == 0:
    return

  colwidths = None
  for row in table:
    if colwidths is None:
      colwidths = [num_codepoints(x) for x in row]
    else:
      colwidths = [max(colwidths[i], num_codepoints(x))
                   for i, x in enumerate(row)]

  if align is None:  # pragma: no cover
    align = 'l' * len(colwidths)

  for row in table:
    cells = []
    for i, cell in enumerate(row):
      padding = ' ' * (colwidths[i] - num_codepoints(cell))
      if align[i] == 'r':
        cell = padding + cell
      elif i < len(row) - 1:
        # Do not pad the final column if left-aligned.
        cell += padding
      cells.append(cell)
    try:
      print(*cells, sep=colsep, end=rowsep, file=out)
    except IOError:  # pragma: no cover
      # Can happen on Windows if the pipe is closed early.
      pass


def pretty_print(parsedblame, show_filenames=False, out=sys.stdout):
  """Pretty-prints the output of parse_blame."""
  table = []
  for line in parsedblame:
    author_time = git_dates.timestamp_offset_to_datetime(
        line.commit.author_time, line.commit.author_tz)
    row = [line.commit.commithash[:8],
           '(' + line.commit.author,
           git_dates.datetime_string(author_time),
           str(line.lineno_now) + ('*' if line.modified else '') + ')',
           line.context]
    if show_filenames:
      row.insert(1, line.commit.filename)
    table.append(row)
  print_table(table, align='llllrl' if show_filenames else 'lllrl', out=out)


def get_parsed_blame(filename, revision='HEAD'):
  blame = git_common.blame(filename, revision=revision, porcelain=True)
  return list(parse_blame(blame))


# Map from (oldrev, newrev) to hunk list (caching the results of git diff, but
# only the hunk line numbers, not the actual diff contents).
# hunk list contains (old, new) pairs, where old and new are (start, length)
# pairs. A hunk list can also be None (if the diff failed).
diff_hunks_cache = {}


def cache_diff_hunks(oldrev, newrev):
  def parse_start_length(s):
    # Chop the '-' or '+'.
    s = s[1:]
    # Length is optional (defaults to 1).
    try:
      start, length = s.split(',')
    except ValueError:
      start = s
      length = 1
    return int(start), int(length)

  try:
    return diff_hunks_cache[(oldrev, newrev)]
  except KeyError:
    pass

  # Use -U0 to get the smallest possible hunks.
  diff = git_common.diff(oldrev, newrev, '-U0')

  # Get all the hunks.
  hunks = []
  for line in diff.split('\n'):
    if not line.startswith('@@'):
      continue
    ranges = line.split(' ', 3)[1:3]
    ranges = tuple(parse_start_length(r) for r in ranges)
    hunks.append(ranges)

  diff_hunks_cache[(oldrev, newrev)] = hunks
  return hunks


def approx_lineno_across_revs(filename, newfilename, revision, newrevision,
                              lineno):
  """Computes the approximate movement of a line number between two revisions.

  Consider line |lineno| in |filename| at |revision|. This function computes the
  line number of that line in |newfilename| at |newrevision|. This is
  necessarily approximate.

  Args:
    filename: The file (within the repo) at |revision|.
    newfilename: The name of the same file at |newrevision|.
    revision: A git revision.
    newrevision: Another git revision. Note: Can be ahead or behind |revision|.
    lineno: Line number within |filename| at |revision|.

  Returns:
    Line number within |newfilename| at |newrevision|.
  """
  # This doesn't work that well if there are a lot of line changes within the
  # hunk (demonstrated by GitHyperBlameLineMotionTest.testIntraHunkLineMotion).
  # A fuzzy heuristic that takes the text of the new line and tries to find a
  # deleted line within the hunk that mostly matches the new line could help.

  # Use the <revision>:<filename> syntax to diff between two blobs. This is the
  # only way to diff a file that has been renamed.
  old = '%s:%s' % (revision, filename)
  new = '%s:%s' % (newrevision, newfilename)
  hunks = cache_diff_hunks(old, new)

  cumulative_offset = 0

  # Find the hunk containing lineno (if any).
  for (oldstart, oldlength), (newstart, newlength) in hunks:
    cumulative_offset += newlength - oldlength

    if lineno >= oldstart + oldlength:
      # Not there yet.
      continue

    if lineno < oldstart:
      # Gone too far.
      break

    # lineno is in [oldstart, oldlength] at revision; [newstart, newlength] at
    # newrevision.

    # If newlength == 0, newstart will be the line before the deleted hunk.
    # Since the line must have been deleted, just return that as the nearest
    # line in the new file. Caution: newstart can be 0 in this case.
    if newlength == 0:
      return max(1, newstart)

    newend = newstart + newlength - 1

    # Move lineno based on the amount the entire hunk shifted.
    lineno = lineno + newstart - oldstart
    # Constrain the output within the range [newstart, newend].
    return min(newend, max(newstart, lineno))

  # Wasn't in a hunk. Figure out the line motion based on the difference in
  # length between the hunks seen so far.
  return lineno + cumulative_offset


def hyper_blame(ignored, filename, revision='HEAD', out=sys.stdout,
                err=sys.stderr):
  # Map from commit to parsed blame from that commit.
  blame_from = {}

  def cache_blame_from(filename, commithash):
    try:
      return blame_from[commithash]
    except KeyError:
      parsed = get_parsed_blame(filename, commithash)
      blame_from[commithash] = parsed
      return parsed

  try:
    parsed = cache_blame_from(filename, git_common.hash_one(revision))
  except subprocess2.CalledProcessError as e:
    err.write(e.stderr)
    return e.returncode

  new_parsed = []

  # We don't show filenames in blame output unless we have to.
  show_filenames = False

  for line in parsed:
    # If a line references an ignored commit, blame that commit's parent
    # repeatedly until we find a non-ignored commit.
    while line.commit.commithash in ignored:
      if line.commit.previous is None:
        # You can't ignore the commit that added this file.
        break

      previouscommit, previousfilename = line.commit.previous.split(' ', 1)
      parent_blame = cache_blame_from(previousfilename, previouscommit)

      if len(parent_blame) == 0:
        # The previous version of this file was empty, therefore, you can't
        # ignore this commit.
        break

      # line.lineno_then is the line number in question at line.commit. We need
      # to translate that line number so that it refers to the position of the
      # same line on previouscommit.
      lineno_previous = approx_lineno_across_revs(
          line.commit.filename, previousfilename, line.commit.commithash,
          previouscommit, line.lineno_then)
      logging.debug('ignore commit %s on line p%d/t%d/n%d',
                    line.commit.commithash, lineno_previous, line.lineno_then,
                    line.lineno_now)

      # Get the line at lineno_previous in the parent commit.
      assert 1 <= lineno_previous <= len(parent_blame)
      newline = parent_blame[lineno_previous - 1]

      # Replace the commit and lineno_then, but not the lineno_now or context.
      line = BlameLine(newline.commit, line.context, newline.lineno_then,
                       line.lineno_now, True)
      logging.debug('    replacing with %r', line)

    # If any line has a different filename to the file's current name, turn on
    # filename display for the entire blame output.
    if line.commit.filename != filename:
      show_filenames = True

    new_parsed.append(line)

  pretty_print(new_parsed, show_filenames=show_filenames, out=out)

  return 0


def parse_ignore_file(ignore_file):
  for line in ignore_file:
    line = line.split('#', 1)[0].strip()
    if line:
      yield line


def main(args, stdout=sys.stdout, stderr=sys.stderr):
  parser = argparse.ArgumentParser(
      prog='git hyper-blame',
      description='git blame with support for ignoring certain commits.')
  parser.add_argument('-i', metavar='REVISION', action='append', dest='ignored',
                      default=[], help='a revision to ignore')
  parser.add_argument('--ignore-file', metavar='FILE',
                      type=argparse.FileType('r'), dest='ignore_file',
                      help='a file containing a list of revisions to ignore')
  parser.add_argument('--no-default-ignores', dest='no_default_ignores',
                      action='store_true',
                      help='Do not ignore commits from .git-blame-ignore-revs.')
  parser.add_argument('revision', nargs='?', default='HEAD', metavar='REVISION',
                      help='revision to look at')
  parser.add_argument('filename', metavar='FILE', help='filename to blame')

  args = parser.parse_args(args)
  try:
    repo_root = git_common.repo_root()
  except subprocess2.CalledProcessError as e:
    stderr.write(e.stderr)
    return e.returncode

  # Make filename relative to the repository root, and cd to the root dir (so
  # all filenames throughout this script are relative to the root).
  filename = os.path.relpath(args.filename, repo_root)
  os.chdir(repo_root)

  # Normalize filename so we can compare it to other filenames git gives us.
  filename = os.path.normpath(filename)
  filename = os.path.normcase(filename)

  ignored_list = list(args.ignored)
  if not args.no_default_ignores and os.path.exists(DEFAULT_IGNORE_FILE_NAME):
    with open(DEFAULT_IGNORE_FILE_NAME) as ignore_file:
      ignored_list.extend(parse_ignore_file(ignore_file))

  if args.ignore_file:
    ignored_list.extend(parse_ignore_file(args.ignore_file))

  ignored = set()
  for c in ignored_list:
    try:
      ignored.add(git_common.hash_one(c))
    except subprocess2.CalledProcessError as e:
      # Custom warning string (the message from git-rev-parse is inappropriate).
      stderr.write('warning: unknown revision \'%s\'.\n' % c)

  return hyper_blame(ignored, filename, args.revision, out=stdout, err=stderr)


if __name__ == '__main__':  # pragma: no cover
  setup_color.init()
  with git_common.less() as less_input:
    sys.exit(main(sys.argv[1:], stdout=less_input))
