#!/usr/bin/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.

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

import argparse
import filecmp
import fileinput
import md5
import os
import re
import shutil
import sys
import tempfile

# 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 ([^ ]*) .*\{')

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


def generate_api(api_jar, output_filename):
  # Dumps the API in |api_jar| into |outpuf_filename|.

  with open(output_filename, 'w') as output_file:
    output_file.write(
        'DO NOT EDIT THIS FILE, USE update_api.py TO UPDATE IT\n\n')

  # Extract API class files from api_jar.
  temp_dir = tempfile.mkdtemp()
  old_cwd = os.getcwd()
  api_jar_path = os.path.abspath(api_jar)
  os.chdir(temp_dir)
  if os.system('jar xf %s' % api_jar_path):
    print 'ERROR: jar failed on ' + api_jar
    return False
  os.chdir(old_cwd)
  shutil.rmtree(os.path.join(temp_dir, 'META-INF'), ignore_errors=True)

  # Collect names 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()

  # Dump API class files into |output_filename|
  javap_cmd = ('javap -protected %s >> %s' % (' '.join(api_class_files),
      output_filename)).replace('$', '\\$')
  if os.system(javap_cmd):
    print 'ERROR: javap command failed: ' + javap_cmd
    return False
  shutil.rmtree(temp_dir)

  # Strip out pieces we don't need to compare.
  output_file = fileinput.FileInput(output_filename, inplace=True)
  skip_to_next_class = False
  md5_hash = md5.new()
  for line in output_file:
    # Skip 'Compiled from ' lines as they're not part of the API.
    if line.startswith('Compiled from "'):
      continue
    if CLASS_RE.match(line):
      skip_to_next_class = (
          # Skip internal classes, they aren't exposed.
          UNNAMED_CLASS_RE.match(line) or
          # Skip experimental classes, they can be modified.
          'Experimental' in line
      )
    if skip_to_next_class:
      skip_to_next_class = line != '}'
      continue
    md5_hash.update(line)
    sys.stdout.write(line)
  output_file.close()
  with open(output_filename, 'a') as output_file:
    output_file.write('Stamp: %s\n' % md5_hash.hexdigest())
  return True


def check_up_to_date(api_jar):
  # Returns True if API_FILENAME matches the API exposed by |api_jar|.

  [_, temp_filename] = tempfile.mkstemp()
  if not generate_api(api_jar, temp_filename):
    return False
  ret = filecmp.cmp(API_FILENAME, temp_filename)
  os.remove(temp_filename)
  return ret


def check_api_update(old_api, new_api):
  # Enforce that lines are only added when updating API.
  new_hash = md5.new()
  old_hash = md5.new()
  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)
        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)
  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')
  opts = parser.parse_args(args)

  if check_up_to_date(opts.api_jar):
    return True

  [_, temp_filename] = tempfile.mkstemp()
  if (generate_api(opts.api_jar, temp_filename) and
      check_api_update(API_FILENAME, temp_filename)):
    # 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.move(temp_filename, API_FILENAME)
    return True
  os.remove(temp_filename)
  return False


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