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