#!/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 pathlib
import subprocess
import sys
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_BUILD_DIR = os.path.join(SRC_DIR, 'out_aar')
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,
        default=DEFAULT_BUILD_DIR,
        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', 'siso', 'cipd', 'siso'),
        '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),
        'android_static_analysis': "off",
        'use_siso': True,
    }
    if use_remoteexec:
        gn_args.update({
            'use_remoteexec': True,
            'use_reclient': False,
        })
    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(['-remote_jobs', '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(build_dir,
             archs,
             output_file,
             use_remoteexec=False,
             extra_gn_args=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 []

    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)


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

    if not pathlib.Path(args.build_dir).is_relative_to(SRC_DIR):
        logging.error('--build-dir must be under %s.', SRC_DIR)
        return 1

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


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