#!/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.

import argparse
import platform
import subprocess
import shutil
import sys
import os

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

ARCH_SUBPATH = 'mac-arm64' if platform.processor() == 'arm' else 'mac-x64'
DSYMUTIL = os.path.join(
    os.path.dirname(__file__), '..', '..', '..', 'buildtools', ARCH_SUBPATH, 'clang', 'bin',
    'dsymutil'
)

out_dir = os.path.join(buildroot_dir, 'out')


def main():
  parser = argparse.ArgumentParser(description='Creates FlutterEmbedder.framework for macOS')

  parser.add_argument('--dst', type=str, required=True)
  parser.add_argument('--arm64-out-dir', type=str, required=True)
  parser.add_argument('--x64-out-dir', type=str, required=True)
  parser.add_argument('--strip', action='store_true', default=False)
  parser.add_argument('--dsym', action='store_true', default=False)
  # TODO(godofredoc): Remove after recipes v2 have landed.
  parser.add_argument('--zip', 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 = (
      args.x64_out_dir
      if os.path.isabs(args.x64_out_dir) else os.path.join(buildroot_dir, args.x64_out_dir)
  )

  fat_framework = os.path.join(dst, 'FlutterEmbedder.framework')
  arm64_framework = os.path.join(arm64_out_dir, 'FlutterEmbedder.framework')
  x64_framework = os.path.join(x64_out_dir, 'FlutterEmbedder.framework')

  arm64_dylib = os.path.join(arm64_framework, 'FlutterEmbedder')
  x64_dylib = os.path.join(x64_framework, 'FlutterEmbedder')

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

  if not os.path.isdir(x64_framework):
    print('Cannot find macOS x64 Framework at %s' % x64_framework)
    return 1

  if not os.path.isfile(arm64_dylib):
    print('Cannot find macOS arm64 dylib at %s' % arm64_dylib)
    return 1

  if not os.path.isfile(x64_dylib):
    print('Cannot find macOS x64 dylib at %s' % x64_dylib)
    return 1

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

  shutil.rmtree(fat_framework, True)
  shutil.copytree(arm64_framework, fat_framework, symlinks=True)
  regenerate_symlinks(fat_framework)

  fat_framework_binary = os.path.join(fat_framework, 'Versions', 'A', 'FlutterEmbedder')

  # Create the arm64/x64 fat framework.
  subprocess.check_call([
      'lipo', arm64_dylib, x64_dylib, '-create', '-output', fat_framework_binary
  ])
  process_framework(dst, args, fat_framework, fat_framework_binary)

  return 0


def regenerate_symlinks(fat_framework):
  """Regenerates the symlinks structure.

  Recipes V2 upload artifacts in CAS before integration and CAS follows symlinks.
  This logic regenerates the symlinks in the expected structure.
  """
  if os.path.islink(os.path.join(fat_framework, 'FlutterEmbedder')):
    return
  os.remove(os.path.join(fat_framework, 'FlutterEmbedder'))
  shutil.rmtree(os.path.join(fat_framework, 'Headers'), True)
  shutil.rmtree(os.path.join(fat_framework, 'Modules'), True)
  shutil.rmtree(os.path.join(fat_framework, 'Resources'), True)
  current_version_path = os.path.join(fat_framework, 'Versions', 'Current')
  shutil.rmtree(current_version_path, True)
  os.symlink('A', current_version_path)
  os.symlink(
      os.path.join('Versions', 'Current', 'FlutterEmbedder'),
      os.path.join(fat_framework, 'FlutterEmbedder')
  )
  os.symlink(os.path.join('Versions', 'Current', 'Headers'), os.path.join(fat_framework, 'Headers'))
  os.symlink(os.path.join('Versions', 'Current', 'Modules'), os.path.join(fat_framework, 'Modules'))
  os.symlink(
      os.path.join('Versions', 'Current', 'Resources'), os.path.join(fat_framework, 'Resources')
  )


def process_framework(dst, args, fat_framework, fat_framework_binary):
  if args.dsym:
    dsym_out = os.path.splitext(fat_framework)[0] + '.dSYM'
    subprocess.check_call([DSYMUTIL, '-o', dsym_out, fat_framework_binary])
    if args.zip:
      dsym_dst = os.path.join(dst, 'FlutterEmbedder.dSYM')
      subprocess.check_call(['zip', '-r', '-y', 'FlutterEmbedder.dSYM.zip', '.'], cwd=dsym_dst)
      dsym_final_src_path = os.path.join(dsym_dst, 'FlutterEmbedder.dSYM.zip')
      dsym_final_dst_path = os.path.join(dst, 'FlutterEmbedder.dSYM.zip')
      shutil.move(dsym_final_src_path, dsym_final_dst_path)

  if args.strip:
    # copy unstripped
    unstripped_out = os.path.join(dst, 'FlutterEmbedder.unstripped')
    shutil.copyfile(fat_framework_binary, unstripped_out)
    subprocess.check_call(['strip', '-x', '-S', fat_framework_binary])

  # Zip FlutterEmbedder.framework.
  if args.zip:
    framework_dst = os.path.join(dst, 'FlutterEmbedder.framework')
    subprocess.check_call([
        'zip',
        '-r',
        '-y',
        'FlutterEmbedder.framework.zip',
        '.',
    ],
                          cwd=framework_dst)
    final_src_path = os.path.join(framework_dst, 'FlutterEmbedder.framework.zip')
    final_dst_path = os.path.join(dst, 'FlutterEmbedder.framework.zip')
    shutil.move(final_src_path, final_dst_path)


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