#!/usr/bin/env python

# 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.
"""WebRTC iOS FAT libraries build script.
Each architecture is compiled separately before being merged together.
By default, the library is created in out_ios_libs/. (Change with -o.)
"""

import argparse
import distutils.dir_util
import logging
import os
import shutil
import subprocess
import sys

os.environ['PATH'] = '/usr/libexec' + os.pathsep + os.environ['PATH']

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..'))
sys.path.append(os.path.join(SRC_DIR, 'build'))
import find_depot_tools

SDK_OUTPUT_DIR = os.path.join(SRC_DIR, 'out_ios_libs')
SDK_FRAMEWORK_NAME = 'WebRTC.framework'

DEFAULT_ARCHS = ENABLED_ARCHS = ['arm64', 'x64']
IOS_DEPLOYMENT_TARGET = '12.0'
LIBVPX_BUILD_VP9 = False

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


def _ParseArgs():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--build_config',
                        default='release',
                        choices=['debug', 'release'],
                        help='The build config. Can be "debug" or "release". '
                        'Defaults to "release".')
    parser.add_argument(
        '--arch',
        nargs='+',
        default=DEFAULT_ARCHS,
        choices=ENABLED_ARCHS,
        help='Architectures to build. Defaults to %(default)s.')
    parser.add_argument(
        '-c',
        '--clean',
        action='store_true',
        default=False,
        help='Removes the previously generated build output, if any.')
    parser.add_argument(
        '-p',
        '--purify',
        action='store_true',
        default=False,
        help='Purifies the previously generated build output by '
        'removing the temporary results used when (re)building.')
    parser.add_argument(
        '-o',
        '--output-dir',
        type=os.path.abspath,
        default=SDK_OUTPUT_DIR,
        help='Specifies a directory to output the build artifacts to. '
        'If specified together with -c, deletes the dir.')
    parser.add_argument(
        '-r',
        '--revision',
        type=int,
        default=0,
        help='Specifies a revision number to embed if building the framework.')
    parser.add_argument('-e',
                        '--bitcode',
                        action='store_true',
                        default=False,
                        help='Compile with bitcode.')
    parser.add_argument('--verbose',
                        action='store_true',
                        default=False,
                        help='Debug logging.')
    parser.add_argument('--use-goma',
                        action='store_true',
                        default=False,
                        help='Use goma to build.')
    parser.add_argument(
        '--extra-gn-args',
        default=[],
        nargs='*',
        help='Additional GN args to be used during Ninja generation.')

    return parser.parse_args()


def _RunCommand(cmd):
    logging.debug('Running: %r', cmd)
    subprocess.check_call(cmd, cwd=SRC_DIR)


def _CleanArtifacts(output_dir):
    if os.path.isdir(output_dir):
        logging.info('Deleting %s', output_dir)
        shutil.rmtree(output_dir)


def _CleanTemporary(output_dir, architectures):
    if os.path.isdir(output_dir):
        logging.info('Removing temporary build files.')
        for arch in architectures:
            arch_lib_path = os.path.join(output_dir, arch + '_libs')
            if os.path.isdir(arch_lib_path):
                shutil.rmtree(arch_lib_path)


def BuildWebRTC(output_dir, target_arch, flavor, gn_target_name,
                ios_deployment_target, libvpx_build_vp9, use_bitcode, use_goma,
                extra_gn_args):
    output_dir = os.path.join(output_dir, target_arch + '_libs')
    gn_args = [
        'target_os="ios"', 'ios_enable_code_signing=false',
        'use_xcode_clang=true', 'is_component_build=false',
        'rtc_include_tests=false',
    ]

    # Add flavor option.
    if flavor == 'debug':
        gn_args.append('is_debug=true')
    elif flavor == 'release':
        gn_args.append('is_debug=false')
    else:
        raise ValueError('Unexpected flavor type: %s' % flavor)

    gn_args.append('target_cpu="%s"' % target_arch)

    gn_args.append('ios_deployment_target="%s"' % ios_deployment_target)

    gn_args.append('rtc_libvpx_build_vp9=' +
                   ('true' if libvpx_build_vp9 else 'false'))

    gn_args.append('enable_ios_bitcode=' +
                   ('true' if use_bitcode else 'false'))
    gn_args.append('use_goma=' + ('true' if use_goma else 'false'))
    gn_args.append('rtc_enable_symbol_export=true')

    args_string = ' '.join(gn_args + extra_gn_args)
    logging.info('Building WebRTC with args: %s', args_string)

    cmd = [
        sys.executable,
        os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'),
        'gen',
        output_dir,
        '--args=' + args_string,
    ]
    _RunCommand(cmd)
    logging.info('Building target: %s', gn_target_name)

    cmd = [
        os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'ninja'),
        '-C',
        output_dir,
        gn_target_name,
    ]
    if use_goma:
        cmd.extend(['-j', '200'])
    _RunCommand(cmd)


def main():
    args = _ParseArgs()

    logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)

    if args.clean:
        _CleanArtifacts(args.output_dir)
        return 0

    architectures = list(args.arch)
    gn_args = args.extra_gn_args

    if args.purify:
        _CleanTemporary(args.output_dir, architectures)
        return 0

    gn_target_name = 'framework_objc'
    if not args.bitcode:
        gn_args.append('enable_dsyms=true')
    gn_args.append('enable_stripping=true')

    # Build all architectures.
    for arch in architectures:
        BuildWebRTC(args.output_dir, arch, args.build_config, gn_target_name,
                    IOS_DEPLOYMENT_TARGET, LIBVPX_BUILD_VP9, args.bitcode,
                    args.use_goma, gn_args)

    # Create FAT archive.
    lib_paths = [
        os.path.join(args.output_dir, arch + '_libs') for arch in architectures
    ]

    # Combine the slices.
    dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC')
    # Dylibs will be combined, all other files are the same across archs.
    # Use distutils instead of shutil to support merging folders.
    distutils.dir_util.copy_tree(
        os.path.join(lib_paths[0], SDK_FRAMEWORK_NAME),
        os.path.join(args.output_dir, SDK_FRAMEWORK_NAME))
    logging.info('Merging framework slices.')
    dylib_paths = [os.path.join(path, dylib_path) for path in lib_paths]
    out_dylib_path = os.path.join(args.output_dir, dylib_path)
    try:
        os.remove(out_dylib_path)
    except OSError:
        pass
    cmd = ['lipo'] + dylib_paths + ['-create', '-output', out_dylib_path]
    _RunCommand(cmd)

    # Merge the dSYM slices.
    lib_dsym_dir_path = os.path.join(lib_paths[0], 'WebRTC.dSYM')
    if os.path.isdir(lib_dsym_dir_path):
        distutils.dir_util.copy_tree(
            lib_dsym_dir_path, os.path.join(args.output_dir, 'WebRTC.dSYM'))
        logging.info('Merging dSYM slices.')
        dsym_path = os.path.join('WebRTC.dSYM', 'Contents', 'Resources',
                                 'DWARF', 'WebRTC')
        lib_dsym_paths = [os.path.join(path, dsym_path) for path in lib_paths]
        out_dsym_path = os.path.join(args.output_dir, dsym_path)
        try:
            os.remove(out_dsym_path)
        except OSError:
            pass
        cmd = ['lipo'] + lib_dsym_paths + ['-create', '-output', out_dsym_path]
        _RunCommand(cmd)

        # Generate the license file.
        ninja_dirs = [
            os.path.join(args.output_dir, arch + '_libs')
            for arch in architectures
        ]
        gn_target_full_name = '//sdk:' + gn_target_name
        builder = LicenseBuilder(ninja_dirs, [gn_target_full_name])
        builder.GenerateLicenseText(
            os.path.join(args.output_dir, SDK_FRAMEWORK_NAME))

        # Modify the version number.
        # Format should be <Branch cut MXX>.<Hotfix #>.<Rev #>.
        # e.g. 55.0.14986 means branch cut 55, no hotfixes, and revision 14986.
        infoplist_path = os.path.join(args.output_dir, SDK_FRAMEWORK_NAME,
                                      'Info.plist')
        cmd = [
            'PlistBuddy', '-c', 'Print :CFBundleShortVersionString',
            infoplist_path
        ]
        major_minor = subprocess.check_output(cmd).strip()
        version_number = '%s.%s' % (major_minor, args.revision)
        logging.info('Substituting revision number: %s', version_number)
        cmd = [
            'PlistBuddy', '-c', 'Set :CFBundleVersion ' + version_number,
            infoplist_path
        ]
        _RunCommand(cmd)
        _RunCommand(['plutil', '-convert', 'binary1', infoplist_path])

    logging.info('Done.')
    return 0


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