#!/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.
"""WebRTC iOS XCFramework 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 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'
SDK_DSYM_NAME = 'WebRTC.dSYM'
SDK_XCFRAMEWORK_NAME = 'WebRTC.xcframework'

ENABLED_ARCHS = [
    'device:arm64', 'simulator:arm64', 'simulator:x64',
    'catalyst:arm64', 'catalyst:x64',
    'arm64', 'x64'
]
DEFAULT_ARCHS = [
    'device:arm64', 'simulator:arm64', 'simulator:x64'
]
IOS_MINIMUM_DEPLOYMENT_TARGET = {
    'device': '12.0',
    'simulator': '12.0',
    'catalyst': '14.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('--verbose',
                        action='store_true',
                        default=False,
                        help='Debug logging.')
    parser.add_argument('--use-remoteexec',
                        action='store_true',
                        default=False,
                        help='Use RBE to build.')
    parser.add_argument(
        '--deployment-target',
        default=IOS_MINIMUM_DEPLOYMENT_TARGET['device'],
        help='Raise the minimum deployment target to build for. '
        'Cannot be lowered below 12.0 for iOS/iPadOS '
        'and 14.0 for Catalyst.')
    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)
            if os.path.isdir(arch_lib_path):
                shutil.rmtree(arch_lib_path)


def _ParseArchitecture(architectures):
    result = dict()
    for arch in architectures:
        if ":" in arch:
            target_environment, target_cpu = arch.split(":")
        else:
            logging.warning('The environment for build is not specified.')
            logging.warning('It is assumed based on cpu type.')
            logging.warning('See crbug.com/1138425 for more details.')
            if arch == "x64":
                target_environment = "simulator"
            else:
                target_environment = "device"
            target_cpu = arch
        archs = result.get(target_environment)
        if archs is None:
            result[target_environment] = {target_cpu}
        else:
            archs.add(target_cpu)

    return result


def _VersionMax(*versions):
    return max(*versions,
               key=lambda version:
               [int(component) for component in version.split('.')])


def BuildWebRTC(output_dir, target_environment, target_arch, flavor,
                gn_target_name, ios_deployment_target, libvpx_build_vp9,
                use_remoteexec, extra_gn_args):
    gn_args = [
        'target_os="ios"',
        'ios_enable_code_signing=false',
        '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_environment="%s"' % target_environment)

    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('use_lld=true')
    gn_args.append('use_remoteexec=' + ('true' if use_remoteexec else 'false'))
    gn_args.append('rtc_enable_objc_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(SRC_DIR, 'third_party', 'ninja', 'ninja'),
        '-C',
        output_dir,
        gn_target_name,
    ]
    if use_remoteexec:
        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 is typed as Dict[str, Set[str]],
    # where key is for the environment (device or simulator)
    # and value is for the cpu type.
    architectures = _ParseArchitecture(args.arch)
    gn_args = args.extra_gn_args

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

    gn_target_name = 'framework_objc'
    gn_args.append('enable_dsyms=true')
    gn_args.append('enable_stripping=true')

    # Build all architectures.
    framework_paths = []
    all_lib_paths = []
    for (environment, archs) in list(architectures.items()):
        ios_deployment_target = _VersionMax(
            args.deployment_target, IOS_MINIMUM_DEPLOYMENT_TARGET[environment])
        framework_path = os.path.join(args.output_dir, environment)
        framework_paths.append(framework_path)
        lib_paths = []
        for arch in archs:
            lib_path = os.path.join(framework_path, arch + '_libs')
            lib_paths.append(lib_path)
            BuildWebRTC(lib_path, environment, arch, args.build_config,
                        gn_target_name, ios_deployment_target,
                        LIBVPX_BUILD_VP9, args.use_remoteexec, gn_args)
        all_lib_paths.extend(lib_paths)

        # Combine the slices.
        dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC')
        # Dylibs will be combined, all other files are the same across archs.
        shutil.rmtree(os.path.join(framework_path, SDK_FRAMEWORK_NAME),
                      ignore_errors=True)
        shutil.copytree(os.path.join(lib_paths[0], SDK_FRAMEWORK_NAME),
                        os.path.join(framework_path, SDK_FRAMEWORK_NAME),
                        symlinks=True)
        logging.info('Merging framework slices for %s.', environment)
        dylib_paths = [os.path.join(path, dylib_path) for path in lib_paths]
        out_dylib_path = os.path.join(framework_path, dylib_path)
        if os.path.islink(out_dylib_path):
            out_dylib_path = os.path.join(os.path.dirname(out_dylib_path),
                                          os.readlink(out_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], SDK_DSYM_NAME)
        if os.path.isdir(lib_dsym_dir_path):
            shutil.rmtree(os.path.join(framework_path, SDK_DSYM_NAME),
                          ignore_errors=True)
            shutil.copytree(lib_dsym_dir_path,
                            os.path.join(framework_path, SDK_DSYM_NAME))
            logging.info('Merging dSYM slices.')
            dsym_path = os.path.join(SDK_DSYM_NAME, 'Contents', 'Resources',
                                     'DWARF', 'WebRTC')
            lib_dsym_paths = [
                os.path.join(path, dsym_path) for path in lib_paths
            ]
            out_dsym_path = os.path.join(framework_path, dsym_path)
            try:
                os.remove(out_dsym_path)
            except OSError:
                pass
            cmd = ['lipo'
                   ] + lib_dsym_paths + ['-create', '-output', out_dsym_path]
            _RunCommand(cmd)

            # Check for Mac-style WebRTC.framework/Resources/ (for Catalyst)...
            resources_dir = os.path.join(framework_path, SDK_FRAMEWORK_NAME,
                                         'Resources')
            if not os.path.exists(resources_dir):
                # ...then fall back to iOS-style WebRTC.framework/
                resources_dir = os.path.dirname(resources_dir)

            # 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(resources_dir, 'Info.plist')
            cmd = [
                'PlistBuddy', '-c', 'Print :CFBundleShortVersionString',
                infoplist_path
            ]
            major_minor = subprocess.check_output(cmd).decode('utf-8').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])

    xcframework_dir = os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME)
    if os.path.isdir(xcframework_dir):
        shutil.rmtree(xcframework_dir)

    logging.info('Creating xcframework.')
    cmd = ['xcodebuild', '-create-xcframework', '-output', xcframework_dir]

    # Apparently, xcodebuild needs absolute paths for input arguments
    for framework_path in framework_paths:
        cmd += [
            '-framework',
            os.path.abspath(os.path.join(framework_path, SDK_FRAMEWORK_NAME)),
        ]
        dsym_full_path = os.path.join(framework_path, SDK_DSYM_NAME)
        if os.path.exists(dsym_full_path):
            cmd += ['-debug-symbols', os.path.abspath(dsym_full_path)]

    _RunCommand(cmd)

    # Generate the license file.
    logging.info('Generate license file.')
    gn_target_full_name = '//sdk:' + gn_target_name
    builder = LicenseBuilder(all_lib_paths, [gn_target_full_name])
    builder.generate_license_text(
        os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME))

    logging.info('Done.')
    return 0


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