#!/usr/bin/env python3

# Copyright (C) 2017-2019 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.decode(), 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 as 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])
  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, 'w')
  else:
    tmp = None
    out = sys.stdout

  # Print log
  date = time.strftime('%Y-%m-%d')
  for log_name, msg in sorted(logs.items()):
    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()
