#!/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_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-goma',
                      action='store_true',
                      default=False,
                      help='Use goma to build.')
  parser.add_argument('--use-remoteexec',
                      action='store_true',
                      default=False,
                      help='Use RBE 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)
      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 BuildWebRTC(output_dir, target_environment, target_arch, flavor,
                gn_target_name, ios_deployment_target, libvpx_build_vp9,
                use_goma, 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_goma=' + ('true' if use_goma else 'false'))
  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(find_depot_tools.DEPOT_TOOLS_PATH, 'ninja'),
      '-C',
      output_dir,
      gn_target_name,
  ]
  if use_goma or 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()):
    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[environment],
                  LIBVPX_BUILD_VP9, args.use_goma, 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.GenerateLicenseText(
      os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME))

  logging.info('Done.')
  return 0


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