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