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

"""Processes an Android AAR file."""

import argparse
import os
import posixpath
import re
import shutil
import sys
from xml.etree import ElementTree
import zipfile

from util import build_utils
from util import md5_check

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),
                                             os.pardir, os.pardir)))
import gn_helpers


def _IsManifestEmpty(manifest_str):
  """Returns whether the given manifest has merge-worthy elements.

  E.g.: <activity>, <service>, etc.
  """
  doc = ElementTree.fromstring(manifest_str)
  for node in doc:
    if node.tag == 'application':
      if len(node):
        return False
    elif node.tag != 'uses-sdk':
      return False

  return True


def _CreateInfo(aar_file):
  data = {}
  data['aidl'] = []
  data['assets'] = []
  data['resources'] = []
  data['subjars'] = []
  data['subjar_tuples'] = []
  data['has_classes_jar'] = False
  data['has_proguard_flags'] = False
  data['has_native_libraries'] = False
  data['has_r_text_file'] = False
  with zipfile.ZipFile(aar_file) as z:
    data['is_manifest_empty'] = (
        _IsManifestEmpty(z.read('AndroidManifest.xml')))

    for name in z.namelist():
      if name.endswith('/'):
        continue
      if name.startswith('aidl/'):
        data['aidl'].append(name)
      elif name.startswith('res/'):
        data['resources'].append(name)
      elif name.startswith('libs/') and name.endswith('.jar'):
        label = posixpath.basename(name)[:-4]
        label = re.sub(r'[^a-zA-Z0-9._]', '_', label)
        data['subjars'].append(name)
        data['subjar_tuples'].append([label, name])
      elif name.startswith('assets/'):
        data['assets'].append(name)
      elif name.startswith('jni/'):
        data['has_native_libraries'] = True
        if 'native_libraries' in data:
          data['native_libraries'].append(name)
        else:
          data['native_libraries'] = [name]
      elif name == 'classes.jar':
        data['has_classes_jar'] = True
      elif name == 'proguard.txt':
        data['has_proguard_flags'] = True
      elif name == 'R.txt':
        # Some AARs, e.g. gvr_controller_java, have empty R.txt. Such AARs
        # have no resources as well. We treat empty R.txt as having no R.txt.
        data['has_r_text_file'] = (z.read('R.txt').strip() != '')

  return """\
# Generated by //build/android/gyp/aar.py
# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".

""" + gn_helpers.ToGNString(data)


def _AddCommonArgs(parser):
  parser.add_argument('aar_file',
                      help='Path to the AAR file.',
                      type=os.path.normpath)


def main():
  parser = argparse.ArgumentParser(description=__doc__)
  command_parsers = parser.add_subparsers(dest='command')
  subp = command_parsers.add_parser(
      'list', help='Output a GN scope describing the contents of the .aar.')
  _AddCommonArgs(subp)
  subp.add_argument('--output',
                    help='Output file.',
                    default='-')

  subp = command_parsers.add_parser('extract', help='Extracts the .aar')
  _AddCommonArgs(subp)
  subp.add_argument('--output-dir',
                    help='Output directory for the extracted files.',
                    required=True,
                    type=os.path.normpath)
  subp.add_argument('--assert-info-file',
                    help='Path to .info file. Asserts that it matches what '
                         '"list" would output.',
                    type=argparse.FileType('r'))

  args = parser.parse_args()

  if args.command == 'extract':
    if args.assert_info_file:
      expected = _CreateInfo(args.aar_file)
      actual = args.assert_info_file.read()
      if actual != expected:
        raise Exception('android_aar_prebuilt() cached .info file is '
                        'out-of-date. Run gn gen with '
                        'update_android_aar_prebuilts=true to update it.')

    def clobber():
      # Clear previously extracted versions of the AAR if it is obsolete.
      shutil.rmtree(args.output_dir, ignore_errors=True)
      build_utils.ExtractAll(args.aar_file, path=args.output_dir)

    with zipfile.ZipFile(args.aar_file) as zf:
      md5_check.CallAndRecordIfStale(
          clobber, input_paths=[args.aar_file],
          output_paths=[
              os.path.join(args.output_dir, n) for n in zf.namelist()])

  elif args.command == 'list':
    aar_info = _CreateInfo(args.aar_file)
    aar_output_present = args.output != '-' and os.path.isfile(args.output)
    if aar_output_present:
      # Some .info files are read-only, for examples the cipd-controlled ones
      # under third_party/android_deps/repositoty. To deal with these, first
      # that its content is correct, and if it is, exit without touching
      # the file system.
      file_info = open(args.output, 'r').read()
      if file_info == aar_info:
        return

    # Try to write the file. This may fail for read-only ones that were
    # not updated.
    try:
      with open(args.output, 'w') as f:
        f.write(aar_info)
    except IOError as e:
      if not aar_output_present:
        raise e
      raise Exception('Could not update output file: %s\n%s\n' %
                      (args.output, e))

if __name__ == '__main__':
  sys.exit(main())
