#!/usr/bin/env vpython3
# 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.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import subprocess
import sys
import os

SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

def get_out_dir(args):
    if args.target_os is not None:
        target_dir = [args.target_os]
    else:
        target_dir = ['host']

    runtime_mode = args.runtime_mode

    target_dir.append(args.runtime_mode)

    if args.simulator:
        target_dir.append('sim')

    if args.unoptimized:
        target_dir.append('unopt')

    if args.target_os != 'ios' and args.interpreter:
        target_dir.append('interpreter')

    if args.android_cpu != 'arm':
        target_dir.append(args.android_cpu)

    if args.ios_cpu != 'arm64':
        target_dir.append(args.ios_cpu)

    if args.mac_cpu != 'x64':
      target_dir.append(args.mac_cpu)

    if args.simulator_cpu != 'x64':
        target_dir.append(args.simulator_cpu)

    if args.linux_cpu is not None:
      target_dir.append(args.linux_cpu)

    if args.windows_cpu != 'x64':
      target_dir.append(args.windows_cpu)

    if args.target_os == 'fuchsia' and args.fuchsia_cpu is not None:
      target_dir.append(args.fuchsia_cpu)

    # This exists for backwards compatibility of tests that are being run
    # on LUCI. This can be removed in coordination with a LUCI change:
    # https://github.com/flutter/flutter/issues/76547
    if args.macos_enable_metal:
      target_dir.append('metal')

    return os.path.join(args.out_dir, 'out', '_'.join(target_dir))

def to_command_line(gn_args):
    """Converts the arguments dictionary to a list of command-line arguments.

    Args:
      gn_args: GN arguments dictionary generated by to_gn_args().
    """
    def merge(key, value):
        if type(value) is bool:
            return '%s=%s' % (key, 'true' if value else 'false')
        return '%s="%s"' % (key, value)
    return [merge(x, y) for x, y in gn_args.items()]

def cpu_for_target_arch(arch):
  if arch in ['ia32', 'arm', 'armv6', 'armv5te', 'mips',
              'simarm', 'simarmv6', 'simarmv5te', 'simmips', 'simdbc',
              'armsimdbc']:
    return 'x86'
  if arch in ['x64', 'arm64', 'simarm64', 'simdbc64', 'armsimdbc64']:
    return 'x64'

def is_host_build(args):
    # If target_os == None, then this is a host build.
    # However, for linux arm64 builds, we cross compile from x64 hosts, so the
    # target_os='linux' and linux-cpu='arm64'
    # TODO(fujino): make host platform explicit
    #   https://github.com/flutter/flutter/issues/79403
    return args.target_os is None or args.target_os == 'linux'

# Determines whether a prebuilt Dart SDK can be used instead of building one.
# We can use a prebuilt Dart SDK when:
# 1. It is a host build, or a build targeting desktop
# 2. The prebuilt SDK exists under //flutter/prebuilts/$OS-$ARCH.
def can_use_prebuilt_dart(args):
  prebuilt = None
  if args.target_os == None:
    if sys.platform.startswith(('cygwin', 'win')):
      prebuilt = 'windows-x64'
    elif sys.platform == 'darwin':
      prebuilt = 'macos-x64'
    else:
      prebuilt = 'linux-x64'
  elif args.target_os == 'linux' and args.linux_cpu in ['x64', 'arm64']:
    prebuilt = 'linux-%s' % args.linux_cpu
  elif args.target_os == 'mac' and args.mac_cpu in ['x64', 'arm64']:
    prebuilt = 'macos-%s' % args.mac_cpu
  elif args.target_os in ['win', 'winuwp'] and args.windows_cpu == 'x64':
    prebuilt = 'windows-%s' % args.windows_cpu

  prebuilts_dir = None
  if prebuilt != None:
    prebuilts_dir = os.path.join(SRC_ROOT, 'flutter', 'prebuilts', prebuilt)
  return prebuilts_dir != None and os.path.isdir(prebuilts_dir)

def to_gn_args(args):
    if args.simulator:
        if args.target_os == 'android':
            raise Exception('--simulator is not supported on Android')

    runtime_mode = args.runtime_mode

    gn_args = {}

    if args.bitcode:
      if args.target_os != 'ios':
        raise Exception('Bitcode is only supported for iOS')
      if runtime_mode != 'release':
        gn_args['bitcode_marker'] = True

    gn_args['enable_bitcode'] = args.bitcode

    # Skia GN args.
    gn_args['skia_enable_flutter_defines'] = True # Enable Flutter API guards in Skia.
    gn_args['skia_use_dng_sdk'] = False    # RAW image handling.
    gn_args['skia_use_sfntly'] = False     # PDF handling dependency.
    gn_args['skia_enable_pdf'] = False     # PDF handling.
    gn_args['skia_use_x11'] = False        # Never add the X11 dependency (only takes effect on Linux).
    gn_args['skia_use_wuffs'] = True
    gn_args['skia_use_expat'] = args.target_os == 'android'
    gn_args['skia_use_fontconfig'] = args.enable_fontconfig
    gn_args['flutter_use_fontconfig'] = args.enable_fontconfig
    gn_args['flutter_enable_skshaper'] = args.enable_skshaper
    if args.enable_skshaper:
      gn_args['skia_use_icu'] = True
      gn_args['flutter_always_use_skshaper'] = args.always_use_skshaper
    if args.target_os == 'winuwp':
      gn_args['skia_enable_winuwp'] = True
    gn_args['is_official_build'] = True    # Disable Skia test utilities.
    gn_args['dart_component_kind'] = 'static_library' # Always link Dart in statically.
    gn_args['is_debug'] = args.unoptimized
    gn_args['android_full_debug'] = args.target_os == 'android' and args.unoptimized
    if args.clang is None:
      gn_args['is_clang'] = True
    else:
      gn_args['is_clang'] = args.clang

    if args.target_os == 'android' or args.target_os == 'ios':
      gn_args['skia_gl_standard'] = 'gles'
    else:
      # We explicitly don't want to pick GL because we run GLES tests using SwiftShader.
      gn_args['skia_gl_standard'] = ''

    if not sys.platform.startswith(('cygwin', 'win')):
      gn_args['use_clang_static_analyzer'] = args.clang_static_analyzer

    gn_args['embedder_for_target'] = args.embedder_for_target

    gn_args['enable_coverage'] = args.coverage

    if args.operator_new_alignment is not None:
      gn_args['operator_new_alignment'] = args.operator_new_alignment

    enable_lto = args.lto
    if args.unoptimized:
      # There is no point in enabling LTO in unoptimized builds.
      enable_lto = False

    if not sys.platform.startswith('win'):
      # The GN arg is not available in the windows toolchain.
      gn_args['enable_lto'] = enable_lto

    if args.target_os == 'android':
        gn_args['target_os'] = 'android'
    elif args.target_os == 'ios':
        gn_args['target_os'] = 'ios'
        gn_args['use_ios_simulator'] = args.simulator
    elif args.target_os == 'fuchsia':
        gn_args['target_os'] = 'fuchsia'
    elif args.target_os == 'winuwp':
        gn_args['target_os'] = 'winuwp'
    elif args.target_os is not None:
        gn_args['target_os'] = args.target_os

    gn_args['dart_lib_export_symbols'] = False

    if runtime_mode == 'debug':
        gn_args['dart_runtime_mode'] = 'develop'
    elif runtime_mode == 'jit_release':
        gn_args['dart_runtime_mode'] = 'release';
    else:
        gn_args['dart_runtime_mode'] = runtime_mode

    if args.dart_debug:
        gn_args['dart_debug'] = True

    if args.full_dart_debug:
      gn_args['dart_debug'] = True
      gn_args['dart_debug_optimization_level'] = '0'

    if args.target_os == 'android':
        gn_args['target_cpu'] = args.android_cpu
    elif args.target_os == 'ios':
        if args.simulator:
            gn_args['target_cpu'] = args.simulator_cpu
        else:
            gn_args['target_cpu'] = args.ios_cpu
    elif args.target_os == 'mac':
      gn_args['target_cpu'] = args.mac_cpu
    elif args.target_os == 'linux':
      gn_args['target_cpu'] = args.linux_cpu
    elif args.target_os == 'fuchsia':
      gn_args['target_cpu'] = args.fuchsia_cpu
    elif args.target_os == 'win':
      gn_args['target_cpu'] = args.windows_cpu
    else:
        # Building host artifacts
        gn_args['target_cpu'] = 'x64'

    # DBC is not supported anymore.
    if args.interpreter:
      raise Exception('--interpreter is no longer needed on any supported platform.')
    gn_args['dart_target_arch'] = gn_args['target_cpu']

    if sys.platform.startswith(('cygwin', 'win')) and args.target_os != 'win':
      if 'target_cpu' in gn_args:
        gn_args['target_cpu'] = cpu_for_target_arch(gn_args['target_cpu'])

    if args.target_os is None:
      if sys.platform.startswith(('cygwin', 'win')):
        gn_args['dart_use_fallback_root_certificates'] = True


    # Make sure host_cpu matches the bit width of target_cpu on x86.
    if gn_args['target_cpu'] == 'x86':
      gn_args['host_cpu'] = 'x86'

    gn_args['flutter_runtime_mode'] = runtime_mode

    if args.target_sysroot:
      gn_args['target_sysroot'] = args.target_sysroot
      gn_args['custom_sysroot'] = args.target_sysroot

    if args.target_toolchain:
      gn_args['custom_toolchain'] = args.target_toolchain

    if args.target_triple:
      gn_args['custom_target_triple'] = args.target_triple

    goma_dir = os.environ.get('GOMA_DIR')
    goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma')
    depot_tools_bin_dir = os.path.join(args.depot_tools, '.cipd_bin')

    # GOMA has a different default (home) path on gWindows.
    if not os.path.exists(goma_home_dir) and sys.platform.startswith(('cygwin', 'win')):
      goma_home_dir = os.path.join('c:\\', 'src', 'goma', 'goma-win64')

    if args.goma and goma_dir:
      gn_args['use_goma'] = True
      gn_args['goma_dir'] = goma_dir
    elif args.goma and os.path.exists(goma_home_dir):
      gn_args['use_goma'] = True
      gn_args['goma_dir'] = goma_home_dir
    elif args.goma and os.path.exists(depot_tools_bin_dir):
      gn_args['use_goma'] = True
      gn_args['goma_dir'] = depot_tools_bin_dir
    else:
      if args.goma:
        print("GOMA usage was specified but can't be found, falling back to local builds. Set the GOMA_DIR environment variable to fix GOMA.")
      gn_args['use_goma'] = False
      gn_args['goma_dir'] = None

    if gn_args['use_goma']:
      if args.xcode_symlinks or os.getenv('FLUTTER_GOMA_CREATE_XCODE_SYMLINKS', '0') == '1':
        gn_args['create_xcode_symlinks'] = True

    # Enable Metal on iOS builds.
    if args.target_os == 'ios':
      gn_args['skia_use_metal'] = True
      gn_args['shell_enable_metal'] = True
      # Bitcode enabled builds using the current version of the toolchain leak
      # C++ symbols decorated with the availability attribute. Disable these
      # attributes in release modes till the toolchain is updated.
      gn_args['skia_enable_api_available_macro'] = args.runtime_mode != "release"

    if sys.platform == 'darwin' and args.target_os not in ['android', 'fuchsia']:
      # OpenGL is deprecated on macOS > 10.11.
      # This is not necessarily needed but enabling this until we have a way to
      # build a macOS metal only shell and a gl only shell.
      gn_args['allow_deprecated_api_calls'] = True
      gn_args['skia_use_metal'] = True
      gn_args['shell_enable_metal'] = True

    if sys.platform.startswith(('cygwin', 'win')):
      # The buildroot currently isn't set up to support Vulkan in the
      # Windows ANGLE build, so disable it regardless of enable_vulkan's value.
      gn_args['angle_enable_vulkan'] = False
      # Don't build unnecessary portions of the ANGLE tree.
      gn_args['angle_build_all'] = False

    # We should not need a special case for x86, but this seems to introduce text relocations
    # even with -fPIC everywhere.
    # gn_args['enable_profiling'] = args.runtime_mode != 'release' and args.android_cpu != 'x86'

    # Make symbols visible in order to enable symbolization of unit test crash backtraces on Linux
    gn_args['disable_hidden_visibility'] = args.target_os == 'linux' and args.unoptimized

    if args.arm_float_abi:
      gn_args['arm_float_abi'] = args.arm_float_abi

    # If we have a prebuilt for the Dart SDK for the target architecture, then
    # use it instead of building a new one.
    if args.prebuilt_dart_sdk:
      if can_use_prebuilt_dart(args):
        print('Using prebuilt Dart SDK binary. If you are editing Dart sources '
              'and wish to compile the Dart SDK, set `--no-prebuilt-dart-sdk`.')
        gn_args['flutter_prebuilt_dart_sdk'] = True
        gn_args['dart_sdk_output'] = 'built-dart-sdk'
      elif is_host_build(args):
        print('Tried to download prebuilt Dart SDK but an appropriate version '
                'could not be found!')
        print('Either retry by running '
              'flutter/tools/download_dart_sdk.py manually or compile from '
              'source by setting `--no-prebuilt-dart-sdk` flag to tools/gn')
    elif is_host_build(args):
      # dart_platform_sdk is only defined for host builds, linux arm host builds
      # specify target_os=linux.
      # dart_platform_sdk=True means exclude web-related files, e.g. dart2js,
      # dartdevc, web SDK kernel and source files.
      gn_args['dart_platform_sdk'] = not args.full_dart_sdk
    gn_args['full_dart_sdk'] = args.full_dart_sdk

    # Desktop embeddings can have more dependencies than the engine library,
    # which can be problematic in some build environments (e.g., building on
    # Linux will bring in pkg-config dependencies at generation time). These
    # flags allow preventing those those targets from being part of the build
    # tree.
    gn_args['enable_desktop_embeddings'] = not args.disable_desktop_embeddings
    if args.build_glfw_shell is not None:
      gn_args['build_glfw_shell'] = args.build_glfw_shell

    gn_args['stripped_symbols'] = args.stripped

    if args.msan:
      gn_args['is_msan'] = True

    if args.asan:
      gn_args['is_asan'] = True

    if args.tsan:
      gn_args['is_tsan'] = True

    if args.lsan:
      gn_args['is_lsan'] = True

    if args.ubsan:
      gn_args['is_ubsan'] = True

    if args.enable_vulkan_validation_layers:
      if args.target_os != 'fuchsia':
        print('Vulkan validation layers are currently only supported on Fuchsia targets.')
        sys.exit(1)
      gn_args['enable_vulkan_validation_layers'] = True

    gn_args['dart_version_git_info'] = not args.no_dart_version_git_info

    # Overrides whether Boring SSL is compiled with system as. Only meaningful
    # on Android.
    gn_args['bssl_use_clang_integrated_as'] = True

    return gn_args

def parse_args(args):
  args = args[1:]
  parser = argparse.ArgumentParser(description='A script run` gn gen`.')

  parser.add_argument('--unoptimized', default=False, action='store_true')

  parser.add_argument('--runtime-mode', type=str, choices=['debug', 'profile', 'release', 'jit_release'], default='debug')
  parser.add_argument('--interpreter', default=False, action='store_true')
  parser.add_argument('--dart-debug', default=False, action='store_true', help='Enables assertions in the Dart VM. ' +
      'Does not affect optimization levels. If you need to disable optimizations in Dart, use --full-dart-debug')
  parser.add_argument('--no-dart-version-git-info', default=False, action='store_true',
                      help='Set by default; if unset, turns off the dart SDK git hash check')
  parser.add_argument('--full-dart-debug', default=False, action='store_true', help='Implies --dart-debug ' +
      'and also disables optimizations in the Dart VM making it easier to step through VM code in the debugger.')

  parser.add_argument('--target-os', type=str, choices=['android', 'ios', 'mac', 'linux', 'fuchsia', 'win', 'winuwp'])
  parser.add_argument('--android', dest='target_os', action='store_const', const='android')
  parser.add_argument('--android-cpu', type=str, choices=['arm', 'x64', 'x86', 'arm64'], default='arm')
  parser.add_argument('--ios', dest='target_os', action='store_const', const='ios')
  parser.add_argument('--ios-cpu', type=str, choices=['arm', 'arm64'], default='arm64')
  parser.add_argument('--mac', dest='target_os', action='store_const', const='mac')
  parser.add_argument('--mac-cpu', type=str, choices=['x64', 'arm64'], default='x64')
  parser.add_argument('--simulator', action='store_true', default=False)
  parser.add_argument('--linux', dest='target_os', action='store_const', const='linux')
  parser.add_argument('--fuchsia', dest='target_os', action='store_const', const='fuchsia')
  parser.add_argument('--winuwp', dest='target_os', action='store_const', const='winuwp')

  parser.add_argument('--linux-cpu', type=str, choices=['x64', 'x86', 'arm64', 'arm'])
  parser.add_argument('--fuchsia-cpu', type=str, choices=['x64', 'arm64'], default = 'x64')
  parser.add_argument('--windows-cpu', type=str, choices=['x64', 'arm64'], default = 'x64')
  parser.add_argument('--simulator-cpu', type=str, choices=['x64', 'arm64'], default = 'x64')
  parser.add_argument('--arm-float-abi', type=str, choices=['hard', 'soft', 'softfp'])

  parser.add_argument('--goma', default=True, action='store_true')
  parser.add_argument('--no-goma', dest='goma', action='store_false')
  parser.add_argument('--xcode-symlinks', action='store_true', help='Set to true for builds targeting macOS or iOS ' +
      'when using goma. If set, symlinks to the Xcode provided sysroot and SDKs will be created in a generated ' +
      'folder, which will avoid potential backend errors in Fuchsia RBE. Instead of specifying the flag on each invocation ' +
      'the FLUTTER_GOMA_CREATE_XCODE_SYMLINKS environment variable may be set to 1 to achieve the same effect.')
  parser.add_argument('--no-xcode-symlinks', dest='xcode_symlinks', default=False, action='store_false')
  parser.add_argument('--depot-tools', default='~/depot_tools', type=str,
                      help='Depot tools provides an alternative location for gomacc in ' +
                      '/path/to/depot_tools/.cipd_bin')

  parser.add_argument('--lto', default=True, action='store_true')
  parser.add_argument('--no-lto', dest='lto', action='store_false')

  parser.add_argument('--clang', action='store_const', const=True)
  parser.add_argument('--no-clang', dest='clang', action='store_const', const=False)

  parser.add_argument('--clang-static-analyzer', default=False, action='store_true')
  parser.add_argument('--no-clang-static-analyzer', dest='clang_static_analyzer', action='store_false')

  parser.add_argument('--target-sysroot', type=str)
  parser.add_argument('--target-toolchain', type=str)
  parser.add_argument('--target-triple', type=str)
  parser.add_argument('--operator-new-alignment', dest='operator_new_alignment', type=str, default=None)

  parser.add_argument('--macos-enable-metal', action='store_true', default=False)
  parser.add_argument('--enable-vulkan', action='store_true', default=False)

  parser.add_argument('--enable-fontconfig', action='store_true', default=False)
  parser.add_argument('--enable-vulkan-validation-layers', action='store_true', default=False)

  parser.add_argument('--enable-skshaper', action='store_true', default=True)
  parser.add_argument('--no-enable-skshaper', dest='enable_skshaper', action='store_false')
  parser.add_argument('--always-use-skshaper', action='store_true', default=False)

  parser.add_argument('--embedder-for-target', dest='embedder_for_target', action='store_true', default=False)

  parser.add_argument('--coverage', default=False, action='store_true')

  parser.add_argument('--out-dir', default='', type=str)

  parser.add_argument('--full-dart-sdk', default=False, action='store_true',
                      help='include trained dart2js and dartdevc snapshots. Enable only on steps that create an SDK')
  parser.add_argument('--no-full-dart-sdk', dest='full_dart_sdk', action='store_false')

  parser.add_argument('--ide', default='', type=str,
                      help='The IDE files to generate using GN. Use `gn gen help` and look for the --ide flag to' +
                      ' see supported IDEs. If this flag is not specified, a platform specific default is selected.')

  parser.add_argument('--disable-desktop-embeddings', default=False, action='store_true',
                      help='Do not include desktop embeddings in the build.')
  parser.add_argument('--build-glfw-shell', action='store_const', const=True,
                      help='Build the GLFW shell on supported platforms where it is not built by default.')
  parser.add_argument('--no-build-glfw-shell', dest='build_glfw_shell', action='store_const', const=False,
                      help='Do not build the GLFW shell on platforms where it is built by default.')

  parser.add_argument('--bitcode', default=False, action='store_true',
                      help='Enable bitcode for iOS targets. On debug runtime modes, this will be a marker only.')

  parser.add_argument('--stripped', default=True, action='store_true',
                      help='Strip debug symbols from the output. This defaults to true and has no effect on iOS.')
  parser.add_argument('--no-stripped', dest='stripped', action='store_false')

  parser.add_argument('--prebuilt-dart-sdk', default=True, action='store_true',
                      help='Whether to use a prebuilt Dart SDK instead of building one. This defaults to ' +
                      'true and is enabled on CI.')
  parser.add_argument('--no-prebuilt-dart-sdk', dest='prebuilt_dart_sdk', action='store_false')

  # Sanitizers.
  parser.add_argument('--asan', default=False, action='store_true')
  parser.add_argument('--lsan', default=False, action='store_true')
  parser.add_argument('--msan', default=False, action='store_true')
  parser.add_argument('--tsan', default=False, action='store_true')
  parser.add_argument('--ubsan', default=False, action='store_true')

  parser.add_argument('--trace-gn', default=False, action='store_true',
                       help='Write a GN trace log (gn_trace.json) in the Chromium tracing format in the build directory.')

  return parser.parse_args(args)

def main(argv):
  args = parse_args(argv)

  exe = '.exe' if sys.platform.startswith(('cygwin', 'win')) else ''

  command = [
    '%s/flutter/third_party/gn/gn%s' % (SRC_ROOT, exe),
    'gen',
    '--check',
    '--export-compile-commands',
  ]

  if args.ide != '':
    command.append('--ide=%s' % args.ide)
  elif sys.platform == 'darwin':
    # On the Mac, generate an Xcode project by default.
    command.append('--ide=xcode')
    command.append('--xcode-project=flutter_engine')
    command.append('--xcode-build-system=new')
  elif sys.platform.startswith('win'):
    # On Windows, generate a Visual Studio project.
    command.append('--ide=vs')

  gn_args = to_command_line(to_gn_args(args))
  out_dir = get_out_dir(args)
  command.append(out_dir)
  command.append('--args=%s' % ' '.join(gn_args))

  if args.trace_gn:
    command.append('--tracelog=%s/gn_trace.json' % out_dir)

  print("Generating GN files in: %s" % out_dir)
  try:
    gn_call_result = subprocess.call(command, cwd=SRC_ROOT)
  except subprocess.CalledProcessError as exc:
    print("Failed to generate gn files: ", exc.returncode, exc.output)
    sys.exit(1)

  return gn_call_result

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