#!/usr/bin/env python3
# Copyright 2016 The Dart 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.

import argparse
import os
import platform
import subprocess
import socket
import sys
import time
import utils

HOST_OS = utils.GuessOS()
HOST_ARCH = utils.GuessArchitecture()
SCRIPT_DIR = os.path.dirname(sys.argv[0])
DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
AVAILABLE_ARCHS = utils.ARCH_FAMILY.keys()

# Environment variables for default settings.
DART_USE_TOOLCHAIN = "DART_USE_TOOLCHAIN"  # Use instead of --toolchain-prefix
DART_USE_SYSROOT = "DART_USE_SYSROOT"  # Use instead of --target-sysroot
DART_USE_CRASHPAD = "DART_USE_CRASHPAD"  # Use instead of --use-crashpad
# use instead of --platform-sdk
DART_MAKE_PLATFORM_SDK = "DART_MAKE_PLATFORM_SDK"

DART_GN_ARGS = "DART_GN_ARGS"


def ToolchainPrefix(args):
    if args.toolchain_prefix:
        return args.toolchain_prefix
    return os.environ.get(DART_USE_TOOLCHAIN)


def TargetSysroot(args):
    if args.target_sysroot:
        return args.target_sysroot
    return os.environ.get(DART_USE_SYSROOT)


def MakePlatformSDK():
    return DART_MAKE_PLATFORM_SDK in os.environ


def GetGNArgs(args):
    if args.gn_args != None:
        return args.gn_args
    args = os.environ.get(DART_GN_ARGS) or ""
    return args.split()


def GetOutDir(mode, arch, target_os, sanitizer):
    return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, sanitizer)


def ToCommandLine(gn_args):

    def merge(key, value):
        if type(value) is bool:
            return '%s=%s' % (key, 'true' if value else 'false')
        elif type(value) is int:
            return '%s=%d' % (key, value)
        return '%s="%s"' % (key, value)

    return [merge(x, y) for x, y in gn_args.items()]


# The C compiler's target under the host toolchain (DART_HOST_ARCH_***).
def HostCpuForArch(arch):
    arch = arch.split("_")[-1]

    # For each target architecture, we prefer in descending order
    # - using the same architecture for the host (supports all architectures)
    # - using a host architecture with the same word size (supports arm and riscv, which have simulators)
    # - using a host architecture with a different word size (supports only AOT and only 32-bit target on 64-bit host)
    if arch in ['ia32']:
        candidates = ['x86']
    elif arch in ['x64', 'x64c', 'simx64', 'simx64c']:
        candidates = ['x64', 'arm64']
    elif arch in ['arm', 'simarm']:
        candidates = ['arm', 'x86', 'riscv32', 'arm64', 'x64', 'riscv64']
    elif arch in ['arm64', 'arm64c', 'simarm64', 'simarm64c']:
        candidates = ['arm64', 'x64', 'riscv64']
    elif arch in ['riscv32', 'simriscv32']:
        candidates = ['riscv32', 'arm', 'x86', 'riscv64', 'arm64', 'x64']
    elif arch in ['riscv64', 'simriscv64']:
        candidates = ['riscv64', 'arm64', 'x64']
    else:
        raise Exception("Unknown Dart architecture: %s" % arch)

    available = utils.HostArchitectures()
    for candidate in candidates:
        if candidate in available:
            return candidate

    raise Exception(
        "Failed to find a C host architecture for %s. Need one of %s but only %s are available."
        % (arch, candidates, available))


# The C compiler's target under the target toolchain (DART_HOST_ARCH_***).
def TargetCpuForArch(arch):
    # Real target architectures
    if arch.startswith('ia32'):
        return 'x86'
    elif arch.startswith('x64'):
        return 'x64'
    elif arch.startswith('arm64'):
        return 'arm64'
    elif arch.startswith('arm'):
        return 'arm'
    elif arch.startswith('riscv32'):
        return 'riscv32'
    elif arch.startswith('riscv64'):
        return 'riscv64'

    # Simulators
    if arch.endswith('_x64'):
        return 'x64'
    elif arch.endswith('_arm64'):
        return 'arm64'
    elif arch.endswith('_riscv64'):
        return 'riscv64'
    elif arch in ['simarm', 'simriscv32']:
        candidates = ['arm', 'riscv32', 'x86']
    elif arch in ['simx64', 'simx64c', 'simarm64', 'simarm64c', 'simriscv64']:
        candidates = ['arm64', 'riscv64', 'x64']
    else:
        raise Exception("Unknown Dart architecture: %s" % arch)

    available = utils.HostArchitectures()
    for candidate in candidates:
        if candidate in available:
            return candidate

    raise Exception(
        "Failed to find a C target architecture for %s. Need one of %s but only %s are available."
        % (arch, candidates, available))


# The Dart compiler's target (DART_TARGET_ARCH_***)
def DartTargetCpuForArch(arch):
    arch = arch.split("_")[0]
    if arch.startswith("sim"):
        arch = arch[3:]
    if arch.endswith("c"):
        arch = arch[:-1]
    return arch


def IsCompressedPointerArch(arch):
    return "64c" in arch


def HostOsForGn(host_os):
    if host_os.startswith('macos'):
        return 'mac'
    if host_os.startswith('win'):
        return 'win'
    return host_os


# Where string_map is formatted as X1=Y1,X2=Y2 etc.
# If key is X1, returns Y1.
def ParseStringMap(key, string_map):
    for m in string_map.split(','):
        l = m.split('=')
        if l[0] == key:
            return l[1]
    return None


def UseSysroot(args, gn_args):
    # Don't try to use a Linux sysroot if we aren't on Linux.
    if gn_args['target_os'] != 'linux' and HOST_OS != 'linux':
        return False
    # Don't use the sysroot if we're given another sysroot.
    if TargetSysroot(args):
        return False
    # Don't use the sysroot if we're given another toolchain.
    if not gn_args['is_clang']:
        return False
    # Fuchsia's Linux sysroot doesn't support RISCV32
    if gn_args['target_cpu'] in ['riscv32']:
        return False
    # Otherwise use the sysroot.
    return True


def ToGnArgs(args, mode, arch, target_os, sanitizer, verify_sdk_hash,
             git_version):
    gn_args = {}

    host_os = HostOsForGn(HOST_OS)
    if target_os == 'host':
        gn_args['target_os'] = host_os
    elif target_os == 'ios_simulator':
        gn_args['target_os'] = 'ios'
        gn_args['use_simulator'] = True
    elif target_os == 'watchos_simulator':
        gn_args['target_os'] = 'watchos'
        gn_args['use_simulator'] = True
    elif target_os == 'watchos':
        gn_args['target_os'] = 'watchos'
    else:
        gn_args['target_os'] = target_os

    gn_args['host_cpu'] = HostCpuForArch(arch)
    gn_args['target_cpu'] = TargetCpuForArch(arch)
    gn_args['dart_target_arch'] = DartTargetCpuForArch(arch)
    if gn_args['target_cpu'] == gn_args['dart_target_arch'] and arch.startswith(
            'sim'):
        gn_args['dart_force_simulator'] = True
    gn_args['dart_use_compressed_pointers'] = IsCompressedPointerArch(arch)

    # Configure Crashpad library if it is used.
    gn_args['dart_use_crashpad'] = ((args.use_crashpad or
                                     DART_USE_CRASHPAD in os.environ) and
                                    gn_args['target_cpu'] in ['x86', 'x64'])
    if gn_args['dart_use_crashpad']:
        # Tell Crashpad's BUILD files which checkout layout to use.
        gn_args['crashpad_dependencies'] = 'dart'

    if DartTargetCpuForArch(arch) != HostCpuForArch(arch):
        # Training an app-jit snapshot under a simulator is slow. Use script
        # snapshots instead.
        gn_args['dart_snapshot_kind'] = 'kernel'
    else:
        gn_args['dart_snapshot_kind'] = 'app-jit'

    # We only want the fallback root certs in the standalone VM on
    # Linux and Windows.
    if gn_args['target_os'] in ['linux', 'win']:
        gn_args['dart_use_fallback_root_certificates'] = True

    if gn_args['target_os'] == 'linux':
        if gn_args['target_cpu'] == 'arm':
            # Default to -mfloat-abi=hard and -mfpu=neon for arm on Linux as we're
            # specifying a gnueabihf compiler in //build/toolchain/linux/BUILD.gn.
            floatabi = 'hard' if args.arm_float_abi == '' else args.arm_float_abi
            gn_args['arm_version'] = 7
            gn_args['arm_float_abi'] = floatabi
            gn_args['arm_use_neon'] = True

    gn_args['is_debug'] = mode == 'debug'
    gn_args['is_release'] = mode == 'release'
    gn_args['is_product'] = mode == 'product'
    gn_args['dart_debug'] = mode == 'debug'

    # This setting is only meaningful for Flutter. Standalone builds of the VM
    # should leave this set to 'develop', which causes the build to defer to
    # 'is_debug', 'is_release' and 'is_product'.
    if mode == 'product':
        gn_args['dart_runtime_mode'] = 'release'
    else:
        gn_args['dart_runtime_mode'] = 'develop'

    gn_args['exclude_kernel_service'] = args.exclude_kernel_service

    gn_args['is_clang'] = args.clang

    enable_code_coverage = args.code_coverage and gn_args['is_clang']
    gn_args['dart_vm_code_coverage'] = enable_code_coverage

    gn_args['dart_dynamic_modules'] = args.dart_dynamic_modules

    gn_args['is_asan'] = sanitizer == 'asan'
    gn_args['is_lsan'] = sanitizer == 'lsan'
    gn_args['is_msan'] = sanitizer == 'msan'
    gn_args['is_tsan'] = sanitizer == 'tsan'
    gn_args['is_ubsan'] = sanitizer == 'ubsan'
    gn_args['is_hwasan'] = sanitizer == 'hwasan'
    gn_args['is_qemu'] = args.use_qemu

    if not args.platform_sdk:
        gn_args['dart_platform_sdk'] = args.platform_sdk

    # We don't support stripping on Windows
    if host_os != 'win':
        gn_args['dart_stripped_binary'] = 'exe.stripped/dart'
        gn_args['dart_aotruntime_stripped_binary'] = (
            'exe.stripped/dartaotruntime_product')
        gn_args['gen_snapshot_stripped_binary'] = (
            'exe.stripped/gen_snapshot_product')
        gn_args['analyze_snapshot_binary'] = ('exe.stripped/analyze_snapshot')
        gn_args['wasm_opt_stripped_binary'] = 'exe.stripped/wasm-opt'

    # Setup the user-defined sysroot.
    if UseSysroot(args, gn_args):
        gn_args['dart_sysroot'] = 'debian'
    else:
        sysroot = TargetSysroot(args)
        if sysroot:
            gn_args['target_sysroot'] = ParseStringMap(arch, sysroot)

        toolchain = ToolchainPrefix(args)
        if toolchain:
            for arch in ['ia32', 'x64', 'arm', 'arm64', 'riscv32', 'riscv64']:
                prefix = ParseStringMap(arch, toolchain)
                if prefix != None:
                    gn_args[arch + '_toolchain_prefix'] = prefix

    gn_args['use_rbe'] = args.rbe

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

    # Code coverage requires -O0 to be set.
    if enable_code_coverage:
        gn_args['dart_debug_optimization_level'] = 0
        gn_args['debug_optimization_level'] = 0
    elif args.debug_opt_level:
        gn_args['dart_debug_optimization_level'] = args.debug_opt_level
        gn_args['debug_optimization_level'] = args.debug_opt_level

    gn_args['verify_sdk_hash'] = verify_sdk_hash
    gn_args['dart_version_git_info'] = git_version

    if args.codesigning_identity != '':
        gn_args['codesigning_identity'] = args.codesigning_identity

    return gn_args


def ProcessOsOption(os_name):
    if os_name == 'host':
        return HOST_OS
    return os_name


def ProcessOptions(args):
    if args.verify_sdk_hash == None:
        args.verify_sdk_hash = not args.rbe
    if args.git_version == None:
        args.git_version = not args.rbe
    if args.arch == 'all':
        if platform.system() == 'Darwin':
            # Targeting 32 bits not supported on MacOS.
            # See HostArchitectures in utils.py.
            args.arch = 'x64,simarm64,x64c,simarm64c,simriscv64'
        else:
            args.arch = 'ia32,x64,simarm,simarm64,x64c,simarm64c,simriscv32,simriscv64'
    if args.mode == 'all':
        args.mode = 'debug,release,product'
    if args.os == 'all':
        args.os = 'host,android,fuchsia'
    if args.sanitizer == 'all':
        args.sanitizer = 'none,asan,lsan,msan,tsan,ubsan'
    args.mode = args.mode.split(',')
    args.arch = args.arch.split(',')
    args.os = args.os.split(',')
    args.sanitizer = args.sanitizer.split(',')
    for mode in args.mode:
        if not mode in ['debug', 'release', 'product']:
            print("Unknown mode %s" % mode)
            return False
    for i, arch in enumerate(args.arch):
        args.arch[i] = arch.lower()
    oses = [ProcessOsOption(os_name) for os_name in args.os]
    for os_name in oses:
        if not os_name in [
                'android', 'freebsd', 'linux', 'macos', 'win32', 'fuchsia',
                'ios', 'ios_simulator', 'watchos', 'watchos_simulator'
        ]:
            print("Unknown os %s" % os_name)
            return False
        if os_name == 'android':
            if not HOST_OS in ['linux', 'macos']:
                print(
                    "Cross-compilation to %s is not supported on host os %s." %
                    (os_name, HOST_OS))
                return False
            if not arch in [
                    'ia32',
                    'x64',
                    'arm',
                    'arm_x64',
                    'arm64',
                    'x64c',
                    'arm64c',
                    'riscv64',
            ]:
                print(
                    "Cross-compilation to %s is not supported for architecture %s."
                    % (os_name, arch))
                return False
        elif os_name == 'fuchsia':
            if not HOST_OS in ['linux', 'macos']:
                print(
                    "Cross-compilation to %s is not supported on host os %s." %
                    (os_name, HOST_OS))
                return False
            if not arch in ['x64', 'arm64', 'x64c', 'arm64c', 'riscv64']:
                print(
                    "Cross-compilation to %s is not supported for architecture %s."
                    % (os_name, arch))
                return False
        elif os_name == 'ios' or os_name == 'ios_simulator' or os_name == 'watchos' or os_name == 'watchos_simulator':
            if not HOST_OS in ['macos']:
                print(f'Target os {os_name} is only supported on macOS')
                return False
        elif os_name != HOST_OS:
            print("Unsupported target os %s" % os_name)
            return False
    if HOST_OS != 'win' and args.use_crashpad:
        print("Crashpad is only supported on Windows")
        return False
    if not args.rbe and \
       (socket.getfqdn().endswith('.corp.google.com') or
        socket.getfqdn().endswith('.c.googlers.com')):
        print('You can speed up your build by following: go/dart-rbe')
    old_rbe_cfg = 'win-intel.cfg' if HOST_OS == 'win32' else 'linux-intel.cfg'
    new_rbe_cfg = 'windows.cfg' if HOST_OS == 'win32' else 'unix.cfg'
    if os.environ.get('RBE_cfg') == os.path.join(os.getcwd(), 'build', 'rbe',
                                                 old_rbe_cfg):
        print(f'warning: {old_rbe_cfg} is deprecated, please update your '
              f'RBE_cfg variable to {new_rbe_cfg} use RBE=1 instead per '
              'go/dart-rbe')
    return True


def os_has_ide(host_os):
    return host_os.startswith('win') or host_os.startswith('mac')


def ide_switch(host_os):
    if host_os.startswith('win'):
        return '--ide=vs'
    elif host_os.startswith('mac'):
        return '--ide=xcode'
    else:
        return '--ide=json'


def AddCommonGnOptionArgs(parser):
    """Adds arguments that will change the default GN arguments."""

    parser.add_argument('--rbe', help='Use rbe', action='store_true')
    parser.add_argument('--no-rbe',
                        help='Disable rbe',
                        dest='rbe',
                        action='store_false')
    parser.set_defaults(rbe=os.environ.get('RBE') == '1' or \
                            os.environ.get('DART_RBE') == '1' or \
                            os.environ.get('RBE_cfg') != None)
    parser.add_argument('--rbe-expensive-exec-strategy',
                        default=os.environ.get('RBE_exec_strategy'),
                        help='Strategy for expensive RBE compilations',
                        type=str)

    # Disable git hashes when remote compiling to ensure cache hits of the final
    # output artifacts when nothing has changed.
    parser.add_argument('--verify-sdk-hash',
                        help='Enable SDK hash checks',
                        dest='verify_sdk_hash',
                        action='store_true')
    parser.add_argument('-nvh',
                        '--no-verify-sdk-hash',
                        help='Disable SDK hash checks',
                        dest='verify_sdk_hash',
                        action='store_false')
    parser.set_defaults(verify_sdk_hash=None)

    parser.add_argument('--git-version',
                        help='Enable git commit in version',
                        dest='git_version',
                        action='store_true')
    parser.add_argument('-ngv',
                        '--no-git-version',
                        help='Disable git commit in version',
                        dest='git_version',
                        action='store_false')
    parser.set_defaults(git_version=None)

    parser.add_argument('--clang', help='Use Clang', action='store_true')
    parser.add_argument('--no-clang',
                        help='Disable Clang',
                        dest='clang',
                        action='store_false')
    parser.set_defaults(clang=True)

    parser.add_argument(
        '--platform-sdk',
        help='Directs the create_sdk target to create a smaller "Platform" SDK',
        default=MakePlatformSDK(),
        action='store_true')
    parser.add_argument('--use-crashpad',
                        default=False,
                        dest='use_crashpad',
                        action='store_true')
    parser.add_argument('--use-qemu',
                        default=False,
                        dest='use_qemu',
                        action='store_true')
    parser.add_argument('--exclude-kernel-service',
                        help='Exclude the kernel service.',
                        default=False,
                        dest='exclude_kernel_service',
                        action='store_true')
    parser.add_argument('--arm-float-abi',
                        type=str,
                        help='The ARM float ABI (soft, softfp, hard)',
                        metavar='[soft,softfp,hard]',
                        default='')

    parser.add_argument('--code-coverage',
                        help='Enable code coverage for the standalone VM',
                        default=False,
                        dest="code_coverage",
                        action='store_true')
    parser.add_argument('--dart-dynamic-modules',
                        help='Enable Dart dynamic modules.',
                        default=False,
                        dest='dart_dynamic_modules',
                        action='store_true')
    parser.add_argument('--debug-opt-level',
                        '-d',
                        help='The optimization level to use for debug builds',
                        type=str)
    parser.add_argument('--gn-args',
                        help='Set extra GN args',
                        dest='gn_args',
                        action='append')
    parser.add_argument(
        '--toolchain-prefix',
        '-t',
        type=str,
        help='Comma-separated list of arch=/path/to/toolchain-prefix mappings')
    parser.add_argument('--ide',
                        help='Generate an IDE file.',
                        default=os_has_ide(HOST_OS),
                        action='store_true')
    parser.add_argument('--export-compile-commands',
                        help='Export compile_commands.json database file.',
                        default=False,
                        action='store_true')
    parser.add_argument(
        '--target-sysroot',
        '-s',
        type=str,
        help='Comma-separated list of arch=/path/to/sysroot mappings')
    parser.add_argument('--use-mallinfo2',
                        help='Use mallinfo2 to collect malloc stats.',
                        default=False,
                        dest='use_mallinfo2',
                        action='store_true')
    parser.add_argument('--codesigning-identity',
                        help='Sign executables using the given identity.',
                        default='',
                        type=str)


def AddCommonConfigurationArgs(parser):
    """Adds arguments that influence which configuration will be built."""
    parser.add_argument("-a",
                        "--arch",
                        type=str,
                        help='Target architectures (comma-separated).',
                        metavar='[all,' + ','.join(AVAILABLE_ARCHS) + ']',
                        default=utils.GuessArchitecture())
    parser.add_argument('--mode',
                        '-m',
                        type=str,
                        help='Build variants (comma-separated).',
                        metavar='[all,debug,release,product]',
                        default='debug')
    parser.add_argument('--os',
                        type=str,
                        help='Target OSs (comma-separated).',
                        metavar='[all,host,android,fuchsia,ios,ios_simulator]',
                        default='host')
    parser.add_argument('--sanitizer',
                        type=str,
                        help='Build variants (comma-separated).',
                        metavar='[all,none,asan,hwasan,lsan,msan,tsan,ubsan]',
                        default='none')


def AddOtherArgs(parser):
    """Adds miscellaneous arguments to the parser."""
    parser.add_argument("-v",
                        "--verbose",
                        help='Verbose output.',
                        default=False,
                        action="store_true")
    parser.add_argument("--test",
                        help='Test this script.',
                        default=False,
                        action="store_true")


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

    config_group = parser.add_argument_group('Configuration Related Arguments')
    AddCommonConfigurationArgs(config_group)

    gn_group = parser.add_argument_group('GN Related Arguments')
    AddCommonGnOptionArgs(gn_group)

    other_group = parser.add_argument_group('Other Arguments')
    AddOtherArgs(other_group)

    options = parser.parse_args(args)
    if not ProcessOptions(options):
        parser.print_help()
        return None
    return options


def InitializeRBE(out_dir, env):
    RBE_cfg = 'RBE_CFG' if HOST_OS == 'win32' else 'RBE_cfg'
    RBE_server_address = ('RBE_SERVER_ADDRESS'
                          if HOST_OS == 'win32' else 'RBE_server_address')
    # Default RBE_cfg to the appropriate configuration file.
    if not RBE_cfg in env:
        env[RBE_cfg] = os.path.join(
            os.getcwd(), 'build', 'rbe',
            'windows.cfg' if HOST_OS == 'win32' else 'unix.cfg')
    # Default RBE_server_address to inside the build directory.
    if not RBE_server_address in env:
        with open(env[RBE_cfg], 'r') as f:
            if not any([l.startswith('server_address') for l in f.readlines()]):
                schema = 'pipe' if HOST_OS == 'win32' else 'unix'
                socket = os.path.join(os.getcwd(), out_dir, 'reproxy.sock')
                if HOST_OS == 'win32':
                    socket = socket.replace('\\', '_').replace(':', '_')
                env[RBE_server_address] = f'{schema}://{socket}'


def ExecutableName(basename):
    if utils.IsWindows():
        return f'{basename}.exe'
    return basename


def BuildGnCommand(args, mode, arch, target_os, sanitizer, out_dir):
    if utils.IsWindows():
        gn = os.path.join(DART_ROOT, 'buildtools', 'win', 'gn.exe')
    else:
        gn = os.path.join(DART_ROOT, 'buildtools', 'gn')
    if not os.path.isfile(gn):
        raise Exception("Couldn't find the gn binary at path: " + gn)

    # TODO(infra): Re-enable --check. Many targets fail to use
    # public_deps to re-expose header files to their dependents.
    # See dartbug.com/32364
    command = [gn, 'gen', out_dir]
    gn_args = ToCommandLine(
        ToGnArgs(args, mode, arch, target_os, sanitizer, args.verify_sdk_hash,
                 args.git_version))
    gn_args += GetGNArgs(args)
    if args.ide:
        command.append(ide_switch(HOST_OS))
    if args.export_compile_commands:
        command.append('--export-compile-commands')
    command.append('--args=%s' % ' '.join(gn_args))

    return command


def RunGnOnConfiguredConfigurations(args, env={}):
    initialized_rbe = False
    commands = []
    for target_os in args.os:
        for mode in args.mode:
            for arch in args.arch:
                for sanitizer in args.sanitizer:
                    out_dir = GetOutDir(mode, arch, target_os, sanitizer)
                    if args.rbe and not initialized_rbe:
                        InitializeRBE(out_dir, env)
                        initialized_rbe = True
                    commands.append(
                        BuildGnCommand(args, mode, arch, target_os, sanitizer,
                                       out_dir))
                    if args.verbose:
                        print("gn gen --check in %s" % out_dir)

    active_commands = []

    def cleanup(command):
        print("Command failed: " + ' '.join(command))
        for (_, process) in active_commands:
            process.terminate()

    for command in commands:
        try:
            process = subprocess.Popen(command, cwd=DART_ROOT, env=env)
            active_commands.append([command, process])
        except Exception as e:
            print('Error: %s' % e)
            cleanup(command)
            return 1
    while active_commands:
        time.sleep(0.1)
        for active_command in active_commands:
            (command, process) = active_command
            if process.poll() is not None:
                active_commands.remove(active_command)
                if process.returncode != 0:
                    cleanup(command)
                    return 1
    return 0


def ExpectEquals(actual, expected):
    if actual != expected:
        raise Exception(f"Actual: {actual} Expected: {expected}")


def RunTests():
    host_arch = utils.HostArchitectures()[0]
    host_arch_or_x64 = host_arch
    if 'x64' in utils.HostArchitectures():
        # Rosetta means 'x64' may be built directly.
        host_arch_or_x64 = 'x64'

    ExpectEquals(HostCpuForArch("arm64"), host_arch)
    ExpectEquals(HostCpuForArch("arm64c"), host_arch)
    ExpectEquals(HostCpuForArch("simarm64"), host_arch)
    ExpectEquals(HostCpuForArch("simarm64_x64"), host_arch_or_x64)
    ExpectEquals(HostCpuForArch("simarm64_arm64"), host_arch)
    ExpectEquals(HostCpuForArch("simarm64_riscv64"), host_arch)
    ExpectEquals(HostCpuForArch("x64"), host_arch_or_x64)
    ExpectEquals(HostCpuForArch("simx64"), host_arch_or_x64)
    ExpectEquals(HostCpuForArch("simx64_x64"), host_arch_or_x64)
    ExpectEquals(HostCpuForArch("simx64_arm64"), host_arch)
    ExpectEquals(HostCpuForArch("simx64_riscv64"), host_arch)

    ExpectEquals(TargetCpuForArch("arm64"), "arm64")
    ExpectEquals(TargetCpuForArch("arm64c"), "arm64")
    ExpectEquals(TargetCpuForArch("simarm64"), host_arch)
    ExpectEquals(TargetCpuForArch("simarm64_x64"), "x64")
    ExpectEquals(TargetCpuForArch("simarm64_arm64"), "arm64")
    ExpectEquals(TargetCpuForArch("simarm64_riscv64"), "riscv64")
    ExpectEquals(TargetCpuForArch("x64"), "x64")
    ExpectEquals(TargetCpuForArch("simx64"), host_arch)
    ExpectEquals(TargetCpuForArch("simx64_x64"), "x64")
    ExpectEquals(TargetCpuForArch("simx64_arm64"), "arm64")
    ExpectEquals(TargetCpuForArch("simx64_riscv64"), "riscv64")

    ExpectEquals(DartTargetCpuForArch("arm64"), "arm64")
    ExpectEquals(DartTargetCpuForArch("arm64c"), "arm64")
    ExpectEquals(DartTargetCpuForArch("simarm64"), "arm64")
    ExpectEquals(DartTargetCpuForArch("simarm64_x64"), "arm64")
    ExpectEquals(DartTargetCpuForArch("simarm64_arm64"), "arm64")
    ExpectEquals(DartTargetCpuForArch("simarm64_riscv64"), "arm64")
    ExpectEquals(DartTargetCpuForArch("x64"), "x64")
    ExpectEquals(DartTargetCpuForArch("simx64"), "x64")
    ExpectEquals(DartTargetCpuForArch("simx64_x64"), "x64")
    ExpectEquals(DartTargetCpuForArch("simx64_arm64"), "x64")
    ExpectEquals(DartTargetCpuForArch("simx64_riscv64"), "x64")

    ExpectEquals(IsCompressedPointerArch("arm64c"), True)
    ExpectEquals(IsCompressedPointerArch("simarm64c"), True)
    ExpectEquals(IsCompressedPointerArch("simarm64c_x64"), True)
    ExpectEquals(IsCompressedPointerArch("x64c"), True)
    ExpectEquals(IsCompressedPointerArch("simx64c"), True)
    ExpectEquals(IsCompressedPointerArch("simx64c_x64"), True)
    ExpectEquals(IsCompressedPointerArch("arm64"), False)
    ExpectEquals(IsCompressedPointerArch("simarm64"), False)
    ExpectEquals(IsCompressedPointerArch("simarm64_x64"), False)
    ExpectEquals(IsCompressedPointerArch("x64"), False)
    ExpectEquals(IsCompressedPointerArch("simx64"), False)
    ExpectEquals(IsCompressedPointerArch("simx64_x64"), False)

    # Our Android bots:
    ExpectEquals(HostCpuForArch("arm64c"), host_arch)
    ExpectEquals(TargetCpuForArch("arm64c"), 'arm64')
    ExpectEquals(DartTargetCpuForArch("arm64c"), 'arm64')
    ExpectEquals(HostCpuForArch("arm_x64"), host_arch_or_x64)
    ExpectEquals(TargetCpuForArch("arm_x64"), 'arm')
    ExpectEquals(DartTargetCpuForArch("arm_x64"), 'arm')


def Main(argv):
    starttime = time.time()

    args = parse_args(argv)
    if args is None:
        return 1

    if args.test:
        RunTests()
        print("Tests passed.")
        return 0

    result = RunGnOnConfiguredConfigurations(args)

    if args.verbose:
        endtime = time.time()
        print("GN Time: %.3f seconds" % (endtime - starttime))

    return result


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