#!/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(SRC_DIR, 'third_party', 'ninja', '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())
