#!/usr/bin/env python3
# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""update_api.py - Update committed Cronet API."""

import argparse
import filecmp
import hashlib
import os
import re
import shutil
import sys
import tempfile


REPOSITORY_ROOT = os.path.abspath(
    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))

sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp'))
from util import build_utils  # pylint: disable=wrong-import-position

# Filename of dump of current API.
API_FILENAME = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', 'android', 'api.txt'))
# Filename of file containing API version number.
API_VERSION_FILENAME = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..', 'android', 'api_version.txt'))

# Regular expression that catches the beginning of lines that declare classes.
# The first group returned by a match is the class name.
CLASS_RE = re.compile(r'.*(class|interface) ([^ ]*) .*\{')

# Regular expression that matches a string containing an unnamed class name,
# for example 'Foo$1'.
UNNAMED_CLASS_RE = re.compile(r'.*\$[0-9]')

# javap still prints internal (package private, nested...) classes even though
# -protected is passed so they need to be filtered out.
INTERNAL_CLASS_RE = re.compile(
    r'^(?!public ((final|abstract) )?(class|interface)).*')

JAR_PATH = os.path.join(build_utils.JAVA_HOME, 'bin', 'jar')
JAVAP_PATH = os.path.join(build_utils.JAVA_HOME, 'bin', 'javap')


def _split_by_class(javap_output):
  """Splits the combined javap output to separate classes.

   * Removes unneeded comments like "Compiled from ...".
   * Sorts the declarations inside the class.

  Returns an array where each element represents a class.
  """
  current_class_lines = []
  all_classes = []
  for line in javap_output:
    # Lines starting with Compiled from are just comments and not part of the
    # api.
    if line.startswith('Compiled from'):
      continue
    current_class_lines.append(line)
    if line == '}':
      # sort only the lines between the {}.
      current_class_lines = ([current_class_lines[0]] +
                             sorted(current_class_lines[1:-1]) +
                             [current_class_lines[-1]])
      all_classes.append(current_class_lines)
      current_class_lines = []
  return all_classes


def _generate_api(api_jar, output_filename):
  """Dumps the API in |api_jar| into |outpuf_filename|."""
  # Extract API class files from api_jar.
  with tempfile.TemporaryDirectory() as temp_dir:
    api_jar_path = os.path.abspath(api_jar)
    jar_cmd = [os.path.relpath(JAR_PATH, temp_dir), 'xf', api_jar_path]
    build_utils.CheckOutput(jar_cmd, cwd=temp_dir)

    shutil.rmtree(os.path.join(temp_dir, 'META-INF'), ignore_errors=True)

    # Collect paths of all API class files
    api_class_files = []
    for root, _, filenames in os.walk(temp_dir):
      api_class_files += [os.path.join(root, f) for f in filenames]
    api_class_files.sort()

    output_lines = ['DO NOT EDIT THIS FILE, USE update_api.py TO UPDATE IT\n']
    javap_cmd = [JAVAP_PATH, '-protected'] + api_class_files
    javap_output = build_utils.CheckOutput(javap_cmd)

  all_classes = _split_by_class(javap_output.splitlines())
  for class_lines in all_classes:
    first_line = class_lines[0]
    # Skip classes we do not care about.
    if UNNAMED_CLASS_RE.match(first_line) or INTERNAL_CLASS_RE.match(
        first_line):
      continue
    output_lines.extend(class_lines)

  output_string = '\n'.join(output_lines) + '\n'
  md5_hash = hashlib.md5()
  md5_hash.update(output_string.encode('utf-8'))
  output_string += 'Stamp: %s\n' % md5_hash.hexdigest()

  with open(output_filename, 'w') as output_file:
    output_file.write(output_string)


def check_up_to_date(api_jar):
  """Returns True if API_FILENAME matches the API exposed by |api_jar|."""
  with tempfile.NamedTemporaryFile() as temp:
    _generate_api(api_jar, temp.name)
    return filecmp.cmp(API_FILENAME, temp.name)


def _check_api_update(old_api, new_api):
  """Enforce that lines are only added when updating API."""
  new_hash = hashlib.md5()
  old_hash = hashlib.md5()
  seen_stamp = False
  with open(old_api, 'r') as old_api_file, open(new_api, 'r') as new_api_file:
    for old_line in old_api_file:
      while True:
        new_line = new_api_file.readline()
        if seen_stamp:
          print('ERROR: Stamp is not the last line.')
          return False
        if new_line.startswith('Stamp: ') and old_line.startswith('Stamp: '):
          if old_line != 'Stamp: %s\n' % old_hash.hexdigest():
            print('ERROR: Prior api.txt not stamped by update_api.py')
            return False
          if new_line != 'Stamp: %s\n' % new_hash.hexdigest():
            print('ERROR: New api.txt not stamped by update_api.py')
            return False
          seen_stamp = True
          break
        new_hash.update(new_line.encode('utf8'))
        if new_line == old_line:
          break
        if not new_line:
          if old_line.startswith('Stamp: '):
            print('ERROR: New api.txt not stamped by update_api.py')
          else:
            print('ERROR: This API was modified or removed:')
            print('           ' + old_line)
            print('       Cronet API methods and classes cannot be modified.')
          return False
      old_hash.update(old_line.encode('utf8'))
  if not seen_stamp:
    print('ERROR: api.txt not stamped by update_api.py.')
    return False
  return True


def main(args):
  parser = argparse.ArgumentParser(description='Update Cronet api.txt.')
  parser.add_argument('--api_jar',
                      help='Path to API jar (i.e. cronet_api.jar)',
                      required=True,
                      metavar='path/to/cronet_api.jar')
  parser.add_argument(
      '--allow_breaking_api_changes',
      help=
      'If true, allows changing the API surface in a non-backward compatible manner (e.g., deleting existing APIs)',
      required=False,
      default=False,
      action='store_true')
  opts = parser.parse_args(args)

  if check_up_to_date(opts.api_jar):
    return True

  with tempfile.NamedTemporaryFile() as temp:
    _generate_api(opts.api_jar, temp.name)
    if opts.allow_breaking_api_changes or _check_api_update(
        API_FILENAME, temp.name):
      # Update API version number to new version number
      with open(API_VERSION_FILENAME, 'r+') as f:
        version = int(f.read())
        f.seek(0)
        f.write(str(version + 1))
      # Update API file to new API
      shutil.copyfile(temp.name, API_FILENAME)
      return True
  return False


if __name__ == '__main__':
  sys.exit(0 if main(sys.argv[1:]) else -1)
