#!/usr/bin/env python3
#
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Generates and zip the ios flutter framework including the architecture
# dependent snapshot.

import argparse
import os
import shutil
import subprocess
import sys

from create_xcframework import create_xcframework

DSYMUTIL = os.path.join(
    os.path.dirname(__file__), '..', '..', '..', 'buildtools', 'mac-x64',
    'clang', 'bin', 'dsymutil'
)

buildroot_dir = os.path.abspath(
    os.path.join(os.path.realpath(__file__), '..', '..', '..', '..')
)


def main():
  parser = argparse.ArgumentParser(
      description=(
          'Creates Flutter.framework, Flutter.xcframework and '
          'copies architecture-dependent gen_snapshot binaries to output dir'
      )
  )

  parser.add_argument('--dst', type=str, required=True)
  parser.add_argument('--clang-dir', type=str, default='clang_x64')
  parser.add_argument('--x64-out-dir', type=str)
  parser.add_argument('--arm64-out-dir', type=str, required=True)
  parser.add_argument('--simulator-x64-out-dir', type=str, required=True)
  parser.add_argument('--simulator-arm64-out-dir', type=str, required=False)
  parser.add_argument('--strip', action="store_true", default=False)
  parser.add_argument('--dsym', action="store_true", default=False)
  parser.add_argument(
      '--strip-bitcode',
      dest='strip_bitcode',
      action="store_true",
      default=False
  )

  args = parser.parse_args()

  dst = (
      args.dst
      if os.path.isabs(args.dst) else os.path.join(buildroot_dir, args.dst)
  )

  arm64_out_dir = (
      args.arm64_out_dir if os.path.isabs(args.arm64_out_dir) else
      os.path.join(buildroot_dir, args.arm64_out_dir)
  )

  x64_out_dir = None
  if args.x64_out_dir:
    x64_out_dir = (
        args.x64_out_dir if os.path.isabs(args.x64_out_dir) else
        os.path.join(buildroot_dir, args.x64_out_dir)
    )

  simulator_x64_out_dir = None
  if args.simulator_x64_out_dir:
    simulator_x64_out_dir = (
        args.simulator_x64_out_dir if os.path.isabs(args.simulator_x64_out_dir)
        else os.path.join(buildroot_dir, args.simulator_x64_out_dir)
    )

  framework = os.path.join(dst, 'Flutter.framework')
  simulator_framework = os.path.join(dst, 'sim', 'Flutter.framework')
  arm64_framework = os.path.join(arm64_out_dir, 'Flutter.framework')
  simulator_x64_framework = os.path.join(
      simulator_x64_out_dir, 'Flutter.framework'
  )

  simulator_arm64_out_dir = None
  if args.simulator_arm64_out_dir:
    simulator_arm64_out_dir = (
        args.simulator_arm64_out_dir if os.path.isabs(
            args.simulator_arm64_out_dir
        ) else os.path.join(buildroot_dir, args.simulator_arm64_out_dir)
    )

  if args.simulator_arm64_out_dir is not None:
    simulator_arm64_framework = os.path.join(
        simulator_arm64_out_dir, 'Flutter.framework'
    )

  if not os.path.isdir(arm64_framework):
    print('Cannot find iOS arm64 Framework at %s' % arm64_framework)
    return 1

  if not os.path.isdir(simulator_x64_framework):
    print('Cannot find iOS x64 simulator Framework at %s' % simulator_framework)
    return 1

  if not os.path.isfile(DSYMUTIL):
    print('Cannot find dsymutil at %s' % DSYMUTIL)
    return 1

  create_framework(
      args, dst, framework, arm64_framework, simulator_framework,
      simulator_x64_framework, simulator_arm64_framework
  )
  framework_binary = os.path.join(framework, 'Flutter')
  process_framework(args, dst, framework, framework_binary)
  generate_gen_snapshot(args, dst, x64_out_dir, arm64_out_dir)
  zip_archive(dst)


def create_framework(
    args, dst, framework, arm64_framework, simulator_framework,
    simulator_x64_framework, simulator_arm64_framework
):
  arm64_dylib = os.path.join(arm64_framework, 'Flutter')
  simulator_x64_dylib = os.path.join(simulator_x64_framework, 'Flutter')
  simulator_arm64_dylib = os.path.join(simulator_arm64_framework, 'Flutter')
  if not os.path.isfile(arm64_dylib):
    print('Cannot find iOS arm64 dylib at %s' % arm64_dylib)
    return 1

  if not os.path.isfile(simulator_x64_dylib):
    print('Cannot find iOS simulator dylib at %s' % simulator_dylib)
    return 1

  shutil.rmtree(framework, True)
  shutil.copytree(arm64_framework, framework)
  framework_binary = os.path.join(framework, 'Flutter')

  if args.simulator_arm64_out_dir is not None:
    shutil.rmtree(simulator_framework, True)
    shutil.copytree(simulator_arm64_framework, simulator_framework)

    simulator_framework_binary = os.path.join(simulator_framework, 'Flutter')

    # Create the arm64/x64 simulator fat framework.
    subprocess.check_call([
        'lipo', simulator_x64_dylib, simulator_arm64_dylib, '-create',
        '-output', simulator_framework_binary
    ])
    process_framework(
        args, dst, simulator_framework, simulator_framework_binary
    )
    simulator_framework = simulator_framework
  else:
    simulator_framework = simulator_x64_framework

  # Create XCFramework from the arm-only fat framework and the arm64/x64 simulator frameworks, or just the
  # x64 simulator framework if only that one exists.
  xcframeworks = [simulator_framework, framework]
  create_xcframework(location=dst, name='Flutter', frameworks=xcframeworks)

  # Add the x64 simulator into the fat framework
  subprocess.check_call([
      'lipo', arm64_dylib, simulator_x64_dylib, '-create', '-output',
      framework_binary
  ])


def embed_codesign_configuration(config_path, contents):
  with open(config_path, 'w') as f:
    f.write('\n'.join(contents) + '\n')


def zip_archive(dst):
  ios_file_with_entitlements = ['gen_snapshot_arm64']
  ios_file_without_entitlements = [
      'Flutter.xcframework/ios-arm64/Flutter.framework/Flutter',
      'Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter'
  ]
  embed_codesign_configuration(
      os.path.join(dst, 'entitlements.txt'), ios_file_with_entitlements
  )

  embed_codesign_configuration(
      os.path.join(dst, 'without_entitlements.txt'),
      ios_file_without_entitlements
  )

  subprocess.check_call([
      'zip',
      '-r',
      'artifacts.zip',
      'gen_snapshot_arm64',
      'Flutter.xcframework',
      'entitlements.txt',
      'without_entitlements.txt',
  ],
                        cwd=dst)
  if (os.path.exists(os.path.join(dst, 'Flutter.dSYM'))):
    subprocess.check_call(['zip', '-r', 'Flutter.dSYM.zip', 'Flutter.dSYM'],
                          cwd=dst)


def process_framework(args, dst, framework, framework_binary):
  if args.strip_bitcode:
    subprocess.check_call([
        'xcrun', 'bitcode_strip', '-r', framework_binary, '-o', framework_binary
    ])

  if args.dsym:
    dsym_out = os.path.splitext(framework)[0] + '.dSYM'
    subprocess.check_call([DSYMUTIL, '-o', dsym_out, framework_binary])

  if args.strip:
    # copy unstripped
    unstripped_out = os.path.join(dst, 'Flutter.unstripped')
    shutil.copyfile(framework_binary, unstripped_out)

    subprocess.check_call(["strip", "-x", "-S", framework_binary])


def generate_gen_snapshot(args, dst, x64_out_dir, arm64_out_dir):
  if x64_out_dir:
    _generate_gen_snapshot(x64_out_dir, os.path.join(dst, 'gen_snapshot_x64'))

  if arm64_out_dir:
    _generate_gen_snapshot(
        os.path.join(arm64_out_dir, args.clang_dir),
        os.path.join(dst, 'gen_snapshot_arm64')
    )


def _generate_gen_snapshot(directory, destination):
  gen_snapshot_dir = os.path.join(directory, 'gen_snapshot')
  if not os.path.isfile(gen_snapshot_dir):
    print('Cannot find gen_snapshot at %s' % gen_snapshot_dir)
    sys.exit(1)

  subprocess.check_call([
      'xcrun', 'bitcode_strip', '-r', gen_snapshot_dir, '-o', destination
  ])


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