#!/usr/bin/python

# Copyright (C) 2017 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING.  If not, write to
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

# This script parses a .diff file generated with 'diff -up' or 'diff -cp'
# and adds a skeleton ChangeLog file to the file. It does not try to be
# too smart when parsing function names, but it produces a reasonable
# approximation.
#
# This is a straightforward adaptation of original Perl script.
#
# Author: Yury Gribov <tetra2005@gmail.com>

import sys
import re
import os.path
import os
import getopt
import tempfile
import time
import shutil
from subprocess import Popen, PIPE

me = os.path.basename(sys.argv[0])

def error(msg):
  sys.stderr.write("%s: error: %s\n" % (me, msg))
  sys.exit(1)

def warn(msg):
  sys.stderr.write("%s: warning: %s\n" % (me, msg))

class RegexCache(object):
  """Simple trick to Perl-like combined match-and-bind."""

  def __init__(self):
    self.last_match = None

  def match(self, p, s):
    self.last_match = re.match(p, s) if isinstance(p, str) else p.match(s)
    return self.last_match

  def search(self, p, s):
    self.last_match = re.search(p, s) if isinstance(p, str) else p.search(s)
    return self.last_match

  def group(self, n):
    return self.last_match.group(n)

cache = RegexCache()

def print_help_and_exit():
    print """\
Usage: %s [-i | --inline] [PATCH]
Generate ChangeLog template for PATCH.
PATCH must be generated using diff(1)'s -up or -cp options
(or their equivalent in Subversion/git).

When PATCH is - or missing, read standard input.

When -i is used, prepends ChangeLog to PATCH.
If PATCH is not stdin, modifies PATCH in-place, otherwise writes
to stdout.
""" % me
    sys.exit(1)

def run(cmd, die_on_error):
  """Simple wrapper for Popen."""
  proc = Popen(cmd.split(' '), stderr = PIPE, stdout = PIPE)
  (out, err) = proc.communicate()
  if die_on_error and proc.returncode != 0:
    error("`%s` failed:\n" % (cmd, proc.stderr))
  return proc.returncode, out, err

def read_user_info():
  dot_mklog_format_msg = """\
The .mklog format is:
NAME = ...
EMAIL = ...
"""

  # First try to read .mklog config
  mklog_conf = os.path.expanduser('~/.mklog')
  if os.path.exists(mklog_conf):
    attrs = {}
    f = open(mklog_conf, 'rb')
    for s in f:
      if cache.match(r'^\s*([a-zA-Z0-9_]+)\s*=\s*(.*?)\s*$', s):
        attrs[cache.group(1)] = cache.group(2)
    f.close()
    if 'NAME' not in attrs:
      error("'NAME' not present in .mklog")
    if 'EMAIL' not in attrs:
      error("'EMAIL' not present in .mklog")
    return attrs['NAME'], attrs['EMAIL']

  # Otherwise go with git

  rc1, name, _ = run('git config user.name', False)
  name = name.rstrip()
  rc2, email, _ = run('git config user.email', False)
  email = email.rstrip()

  if rc1 != 0 or rc2 != 0:
    error("""\
Could not read git user.name and user.email settings.
Please add missing git settings, or create a %s.
""" % mklog_conf)

  return name, email

def get_parent_changelog (s):
  """See which ChangeLog this file change should go to."""

  if s.find('\\') == -1 and s.find('/') == -1:
    return "ChangeLog", s

  gcc_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

  d = s
  while d:
    clname = d + "/ChangeLog"
    if os.path.exists(gcc_root + '/' + clname) or os.path.exists(clname):
      relname = s[len(d)+1:]
      return clname, relname
    d, _ = os.path.split(d)

  return "Unknown ChangeLog", s

class FileDiff:
  """Class to represent changes in a single file."""

  def __init__(self, filename):
    self.filename = filename
    self.hunks = []
    self.clname, self.relname = get_parent_changelog(filename);

  def dump(self):
    print "Diff for %s:\n  ChangeLog = %s\n  rel name = %s\n" % (self.filename, self.clname, self.relname)
    for i, h in enumerate(self.hunks):
      print "Next hunk %d:" % i
      h.dump()

class Hunk:
  """Class to represent a single hunk of changes."""

  def __init__(self, hdr):
    self.hdr = hdr
    self.lines = []
    self.ctx_diff = is_ctx_hunk_start(hdr)

  def dump(self):
    print '%s' % self.hdr
    print '%s' % '\n'.join(self.lines)

  def is_file_addition(self):
    """Does hunk describe addition of file?"""
    if self.ctx_diff:
      for line in self.lines:
        if re.match(r'^\*\*\* 0 \*\*\*\*', line):
          return True
    else:
      return re.match(r'^@@ -0,0 \+1.* @@', self.hdr)

  def is_file_removal(self):
    """Does hunk describe removal of file?"""
    if self.ctx_diff:
      for line in self.lines:
        if re.match(r'^--- 0 ----', line):
          return True
    else:
      return re.match(r'^@@ -1.* \+0,0 @@', self.hdr)

def is_file_diff_start(s):
  # Don't be fooled by context diff line markers:
  #   *** 385,391 ****
  return ((s.startswith('***') and not s.endswith('***'))
          or (s.startswith('---') and not s.endswith('---')))

def is_ctx_hunk_start(s):
  return re.match(r'^\*\*\*\*\*\**', s)

def is_uni_hunk_start(s):
  return re.match(r'^@@ .* @@', s)

def is_hunk_start(s):
  return is_ctx_hunk_start(s) or is_uni_hunk_start(s)

def remove_suffixes(s):
  if s.startswith('a/') or s.startswith('b/'):
    s = s[2:]
  if s.endswith('.jj'):
    s = s[:-3]
  return s

def find_changed_funs(hunk):
  """Find all functions touched by hunk.  We don't try too hard
     to find good matches.  This should return a superset
     of the actual set of functions in the .diff file.
  """

  fns = []
  fn = None

  if (cache.match(r'^\*\*\*\*\*\** ([a-zA-Z0-9_].*)', hunk.hdr)
      or cache.match(r'^@@ .* @@ ([a-zA-Z0-9_].*)', hunk.hdr)):
    fn = cache.group(1)

  for i, line in enumerate(hunk.lines):
    # Context diffs have extra whitespace after first char;
    # remove it to make matching easier.
    if hunk.ctx_diff:
      line = re.sub(r'^([-+! ]) ', r'\1', line)

    # Remember most recent identifier in hunk
    # that might be a function name.
    if cache.match(r'^[-+! ]([a-zA-Z0-9_#].*)', line):
      fn = cache.group(1)

    change = line and re.match(r'^[-+!][^-]', line)

    # Top-level comment cannot belong to function
    if re.match(r'^[-+! ]\/\*', line):
      fn = None

    if change and fn:
      if cache.match(r'^((class|struct|union|enum)\s+[a-zA-Z0-9_]+)', fn):
        # Struct declaration
        fn = cache.group(1)
      elif cache.search(r'#\s*define\s+([a-zA-Z0-9_]+)', fn):
        # Macro definition
        fn = cache.group(1)
      elif cache.match('^DEF[A-Z0-9_]+\s*\(([a-zA-Z0-9_]+)', fn):
        # Supermacro
        fn = cache.group(1)
      elif cache.search(r'([a-zA-Z_][^()\s]*)\s*\([^*]', fn):
        # Discard template and function parameters.
        fn = cache.group(1)
        fn = re.sub(r'<[^<>]*>', '', fn)
        fn = fn.rstrip()
      else:
        fn = None

      if fn and fn not in fns:  # Avoid dups
        fns.append(fn)

      fn = None

  return fns

def parse_patch(contents):
  """Parse patch contents to a sequence of FileDiffs."""

  diffs = []

  lines = contents.split('\n')

  i = 0
  while i < len(lines):
    line = lines[i]

    # Diff headers look like
    #   --- a/gcc/tree.c
    #   +++ b/gcc/tree.c
    # or
    #   *** gcc/cfgexpand.c     2013-12-25 20:07:24.800350058 +0400
    #   --- gcc/cfgexpand.c     2013-12-25 20:06:30.612350178 +0400

    if is_file_diff_start(line):
      left = re.split(r'\s+', line)[1]
    else:
      i += 1
      continue

    left = remove_suffixes(left);

    i += 1
    line = lines[i]

    if not cache.match(r'^[+-][+-][+-] +(\S+)', line):
      error("expected filename in line %d" % i)
    right = remove_suffixes(cache.group(1));

    # Extract real file name from left and right names.
    filename = None
    if left == right:
      filename = left
    elif left == '/dev/null':
      filename = right;
    elif right == '/dev/null':
      filename = left;
    else:
      comps = []
      while left and right:
        left, l = os.path.split(left)
        right, r = os.path.split(right)
        if l != r:
          break
        comps.append(l)
    
      if not comps:
        error("failed to extract common name for %s and %s" % (left, right))

      comps.reverse()
      filename = '/'.join(comps)

    d = FileDiff(filename)
    diffs.append(d)

    # Collect hunks for current file.
    hunk = None
    i += 1
    while i < len(lines):
      line = lines[i]

      # Create new hunk when we see hunk header
      if is_hunk_start(line):
        if hunk is not None:
          d.hunks.append(hunk)
        hunk = Hunk(line)
        i += 1
        continue

      # Stop when we reach next diff
      if (is_file_diff_start(line)
          or line.startswith('diff ')
          or line.startswith('Index: ')):
        i -= 1
        break

      if hunk is not None:
        hunk.lines.append(line)
      i += 1

    d.hunks.append(hunk)

  return diffs

def main():
  name, email = read_user_info()

  try:
    opts, args = getopt.getopt(sys.argv[1:], 'hiv', ['help', 'verbose', 'inline'])
  except getopt.GetoptError, err:
    error(str(err))

  inline = False
  verbose = 0

  for o, a in opts:
    if o in ('-h', '--help'):
      print_help_and_exit()
    elif o in ('-i', '--inline'):
      inline = True
    elif o in ('-v', '--verbose'):
      verbose += 1
    else:
      assert False, "unhandled option"

  if len(args) == 0:
    args = ['-']

  if len(args) == 1 and args[0] == '-':
    input = sys.stdin
  elif len(args) == 1:
    input = open(args[0], 'rb')
  else:
    error("too many arguments; for more details run with -h")

  contents = input.read()
  diffs = parse_patch(contents)

  if verbose:
    print "Parse results:"
    for d in diffs:
      d.dump()

  # Generate template ChangeLog.

  logs = {}
  for d in diffs:
    log_name = d.clname

    logs.setdefault(log_name, '')
    logs[log_name] += '\t* %s' % d.relname

    change_msg = ''

    # Check if file was removed or added.
    # Two patterns for context and unified diff.
    if len(d.hunks) == 1:
      hunk0 = d.hunks[0]
      if hunk0.is_file_addition():
        if re.search(r'testsuite.*(?<!\.exp)$', d.filename):
          change_msg = ': New test.\n'
        else:
          change_msg = ": New file.\n"
      elif hunk0.is_file_removal():
        change_msg = ": Remove.\n"

    _, ext = os.path.splitext(d.filename)
    if not change_msg and ext in ['.c', '.cpp', '.C', '.cc', '.h', '.inc', '.def']:
      fns = []
      for hunk in d.hunks:
        for fn in find_changed_funs(hunk):
          if fn not in fns:
            fns.append(fn)

      for fn in fns:
        if change_msg:
          change_msg += "\t(%s):\n" % fn
        else:
          change_msg = " (%s):\n" % fn

    logs[log_name] += change_msg if change_msg else ":\n"

  if inline and args[0] != '-':
    # Get a temp filename, rather than an open filehandle, because we use
    # the open to truncate.
    fd, tmp = tempfile.mkstemp("tmp.XXXXXXXX")
    os.close(fd)

    # Copy permissions to temp file
    # (old Pythons do not support shutil.copymode)
    shutil.copymode(args[0], tmp)

    # Open the temp file, clearing contents.
    out = open(tmp, 'wb')
  else:
    tmp = None
    out = sys.stdout

  # Print log
  date = time.strftime('%Y-%m-%d')
  for log_name, msg in sorted(logs.iteritems()):
    out.write("""\
%s:

%s  %s  <%s>

%s\n""" % (log_name, date, name, email, msg))

  if inline:
    # Append patch body
    out.write(contents)

    if args[0] != '-':
      # Write new contents atomically
      out.close()
      shutil.move(tmp, args[0])

if __name__ == '__main__':
    main()
