#!/usr/bin/env vpython3

# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
"""Script to generate libwebrtc.aar for distribution.

The script has to be run from the root src folder.
./tools_webrtc/android/build_aar.py

.aar-file is just a zip-archive containing the files of the library. The file
structure generated by this script looks like this:
 - AndroidManifest.xml
 - classes.jar
 - libs/
   - armeabi-v7a/
     - libjingle_peerconnection_so.so
   - x86/
     - libjingle_peerconnection_so.so
"""

import argparse
import logging
import os
import shutil
import subprocess
import sys
import tempfile
import zipfile

SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
DEFAULT_ARCHS = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']
NEEDED_SO_FILES = ['libjingle_peerconnection_so.so']
JAR_FILE = 'lib.java/sdk/android/libwebrtc.jar'
MANIFEST_FILE = 'sdk/android/AndroidManifest.xml'
TARGETS = [
    'sdk/android:libwebrtc',
    'sdk/android:libjingle_peerconnection_so',
]

sys.path.append(os.path.join(SCRIPT_DIR, '..', 'libs'))
from generate_licenses import LicenseBuilder

sys.path.append(os.path.join(SRC_DIR, 'build'))
import find_depot_tools


def _ParseArgs():
  parser = argparse.ArgumentParser(description='libwebrtc.aar generator.')
  parser.add_argument(
      '--build-dir',
      type=os.path.abspath,
      help='Build dir. By default will create and use temporary dir.')
  parser.add_argument('--output',
                      default='libwebrtc.aar',
                      type=os.path.abspath,
                      help='Output file of the script.')
  parser.add_argument('--arch',
                      default=DEFAULT_ARCHS,
                      nargs='*',
                      help='Architectures to build. Defaults to %(default)s.')
  parser.add_argument('--use-goma',
                      action='store_true',
                      default=False,
                      help='Use goma.')
  parser.add_argument('--use-remoteexec',
                      action='store_true',
                      default=False,
                      help='Use RBE.')
  parser.add_argument('--use-unstripped-libs',
                      action='store_true',
                      default=False,
                      help='Use unstripped .so files within libwebrtc.aar')
  parser.add_argument('--verbose',
                      action='store_true',
                      default=False,
                      help='Debug logging.')
  parser.add_argument(
      '--extra-gn-args',
      default=[],
      nargs='*',
      help="""Additional GN arguments to be used during Ninja generation.
              These are passed to gn inside `--args` switch and
              applied after any other arguments and will
              override any values defined by the script.
              Example of building debug aar file:
              build_aar.py --extra-gn-args='is_debug=true'""")
  parser.add_argument(
      '--extra-ninja-switches',
      default=[],
      nargs='*',
      help="""Additional Ninja switches to be used during compilation.
              These are applied after any other Ninja switches.
              Example of enabling verbose Ninja output:
              build_aar.py --extra-ninja-switches='-v'""")
  parser.add_argument(
      '--extra-gn-switches',
      default=[],
      nargs='*',
      help="""Additional GN switches to be used during compilation.
              These are applied after any other GN switches.
              Example of enabling verbose GN output:
              build_aar.py --extra-gn-switches='-v'""")
  return parser.parse_args()


def _RunGN(args):
  cmd = [
      sys.executable,
      os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py')
  ]
  cmd.extend(args)
  logging.debug('Running: %r', cmd)
  subprocess.check_call(cmd)


def _RunNinja(output_directory, args):
  cmd = [
      os.path.join(SRC_DIR, 'third_party', 'ninja', 'ninja'), '-C',
      output_directory
  ]
  cmd.extend(args)
  logging.debug('Running: %r', cmd)
  subprocess.check_call(cmd)


def _EncodeForGN(value):
  """Encodes value as a GN literal."""
  if isinstance(value, str):
    return '"' + value + '"'
  if isinstance(value, bool):
    return repr(value).lower()
  return repr(value)


def _GetOutputDirectory(build_dir, arch):
  """Returns the GN output directory for the target architecture."""
  return os.path.join(build_dir, arch)


def _GetTargetCpu(arch):
  """Returns target_cpu for the GN build with the given architecture."""
  if arch in ['armeabi', 'armeabi-v7a']:
    return 'arm'
  if arch == 'arm64-v8a':
    return 'arm64'
  if arch == 'x86':
    return 'x86'
  if arch == 'x86_64':
    return 'x64'
  raise Exception('Unknown arch: ' + arch)


def _GetArmVersion(arch):
  """Returns arm_version for the GN build with the given architecture."""
  if arch == 'armeabi':
    return 6
  if arch == 'armeabi-v7a':
    return 7
  if arch in ['arm64-v8a', 'x86', 'x86_64']:
    return None
  raise Exception('Unknown arch: ' + arch)


def Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
          extra_gn_switches, extra_ninja_switches):
  """Generates target architecture using GN and builds it using ninja."""
  logging.info('Building: %s', arch)
  output_directory = _GetOutputDirectory(build_dir, arch)
  gn_args = {
      'target_os': 'android',
      'is_debug': False,
      'is_component_build': False,
      'rtc_include_tests': False,
      'target_cpu': _GetTargetCpu(arch),
      'use_goma': use_goma,
      'use_remoteexec': use_remoteexec,
  }
  arm_version = _GetArmVersion(arch)
  if arm_version:
    gn_args['arm_version'] = arm_version
  gn_args_str = '--args=' + ' '.join(
      [k + '=' + _EncodeForGN(v) for k, v in gn_args.items()] + extra_gn_args)

  gn_args_list = ['gen', output_directory, gn_args_str]
  gn_args_list.extend(extra_gn_switches)
  _RunGN(gn_args_list)

  ninja_args = TARGETS[:]
  if use_goma or use_remoteexec:
    ninja_args.extend(['-j', '200'])
  ninja_args.extend(extra_ninja_switches)
  _RunNinja(output_directory, ninja_args)


def CollectCommon(aar_file, build_dir, arch):
  """Collects architecture independent files into the .aar-archive."""
  logging.info('Collecting common files.')
  output_directory = _GetOutputDirectory(build_dir, arch)
  aar_file.write(MANIFEST_FILE, 'AndroidManifest.xml')
  aar_file.write(os.path.join(output_directory, JAR_FILE), 'classes.jar')


def Collect(aar_file, build_dir, arch, unstripped):
  """Collects architecture specific files into the .aar-archive."""
  logging.info('Collecting: %s', arch)
  output_directory = _GetOutputDirectory(build_dir, arch)

  abi_dir = os.path.join('jni', arch)
  for so_file in NEEDED_SO_FILES:
    source_so_file = os.path.join("lib.unstripped",
                                  so_file) if unstripped else so_file
    aar_file.write(os.path.join(output_directory, source_so_file),
                   os.path.join(abi_dir, so_file))


def GenerateLicenses(output_dir, build_dir, archs):
  builder = LicenseBuilder(
      [_GetOutputDirectory(build_dir, arch) for arch in archs], TARGETS)
  builder.GenerateLicenseText(output_dir)


def BuildAar(archs,
             output_file,
             use_goma=False,
             use_remoteexec=False,
             extra_gn_args=None,
             ext_build_dir=None,
             extra_gn_switches=None,
             extra_ninja_switches=None,
             unstripped=False):
  extra_gn_args = extra_gn_args or []
  extra_gn_switches = extra_gn_switches or []
  extra_ninja_switches = extra_ninja_switches or []
  build_dir = ext_build_dir if ext_build_dir else tempfile.mkdtemp()

  for arch in archs:
    Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
          extra_gn_switches, extra_ninja_switches)

  with zipfile.ZipFile(output_file, 'w') as aar_file:
    # Architecture doesn't matter here, arbitrarily using the first one.
    CollectCommon(aar_file, build_dir, archs[0])
    for arch in archs:
      Collect(aar_file, build_dir, arch, unstripped)

  license_dir = os.path.dirname(os.path.realpath(output_file))
  GenerateLicenses(license_dir, build_dir, archs)

  if not ext_build_dir:
    shutil.rmtree(build_dir, True)


def main():
  args = _ParseArgs()
  logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)

  BuildAar(args.arch, args.output, args.use_goma, args.use_remoteexec,
           args.extra_gn_args, args.build_dir, args.extra_gn_switches,
           args.extra_ninja_switches, args.use_unstripped_libs)


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