#!/usr/bin/env python
#
# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import multiprocessing
import optparse
import os
import subprocess
import sys
import time
import utils

HOST_OS = utils.GuessOS()
HOST_CPUS = utils.GuessCpus()
SCRIPT_DIR = os.path.dirname(sys.argv[0])
DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
AVAILABLE_ARCHS = [
    'ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6', 'simarmv5te',
    'armv5te', 'simarm64', 'arm64', 'simdbc', 'simdbc64', 'armsimdbc',
    'armsimdbc64', 'simarm_x64'
]

usage = """\
usage: %%prog [options] [targets]

This script invokes ninja to build Dart.
"""


def BuildOptions():
    result = optparse.OptionParser(usage=usage)
    result.add_option(
        "-a",
        "--arch",
        help='Target architectures (comma-separated).',
        metavar='[all,' + ','.join(AVAILABLE_ARCHS) + ']',
        default=utils.GuessArchitecture())
    result.add_option(
        "-b",
        "--bytecode",
        help='Build with the kernel bytecode interpreter. DEPRECATED.',
        default=False,
        action='store_true')
    result.add_option(
        "-j", type=int, help='Ninja -j option for Goma builds.', default=1000)
    result.add_option(
        "-l", type=int, help='Ninja -l option for Goma builds.', default=64)
    result.add_option(
        "-m",
        "--mode",
        help='Build variants (comma-separated).',
        metavar='[all,debug,release,product]',
        default='debug')
    result.add_option(
        "--no-start-goma",
        help="Don't try to start goma",
        default=False,
        action='store_true')
    result.add_option(
        "--os",
        help='Target OSs (comma-separated).',
        metavar='[all,host,android]',
        default='host')
    # TODO(38701): Remove this and everything that references it once the
    # forked NNBD SDK is merged back in.
    result.add_option(
        "--nnbd",
        help='Use the NNBD fork of the SDK.',
        default=False,
        action='store_true')
    result.add_option(
        "-v",
        "--verbose",
        help='Verbose output.',
        default=False,
        action="store_true")
    return result


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


def ProcessOptions(options, args):
    if options.arch == 'all':
        options.arch = 'ia32,x64,simarm,simarm64,simdbc64'
    if options.mode == 'all':
        options.mode = 'debug,release,product'
    if options.os == 'all':
        options.os = 'host,android'
    options.mode = options.mode.split(',')
    options.arch = options.arch.split(',')
    options.os = options.os.split(',')
    for mode in options.mode:
        if not mode in ['debug', 'release', 'product']:
            print("Unknown mode %s" % mode)
            return False
    for arch in options.arch:
        if not arch in AVAILABLE_ARCHS:
            print("Unknown arch %s" % arch)
            return False
    options.os = [ProcessOsOption(os_name) for os_name in options.os]
    for os_name in options.os:
        if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
            print("Unknown os %s" % os_name)
            return False
        if os_name != HOST_OS:
            if os_name != 'android':
                print("Unsupported target os %s" % os_name)
                return False
            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', 'armv6', 'armv5te', 'arm64', 'simdbc',
                    'simdbc64'
            ]:
                print(
                    "Cross-compilation to %s is not supported for architecture %s."
                    % (os_name, arch))
                return False
            # We have not yet tweaked the v8 dart build to work with the Android
            # NDK/SDK, so don't try to build it.
            if not args:
                print(
                    "For android builds you must specify a target, such as 'runtime'."
                )
                return False
    return True


def NotifyBuildDone(build_config, success, start):
    if not success:
        print("BUILD FAILED")

    sys.stdout.flush()

    # Display a notification if build time exceeded DART_BUILD_NOTIFICATION_DELAY.
    notification_delay = float(
        os.getenv('DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
    if (time.time() - start) < notification_delay:
        return

    if success:
        message = 'Build succeeded.'
    else:
        message = 'Build failed.'
    title = build_config

    command = None
    if HOST_OS == 'macos':
        # Use AppleScript to display a UI non-modal notification.
        script = 'display notification  "%s" with title "%s" sound name "Glass"' % (
            message, title)
        command = "osascript -e '%s' &" % script
    elif HOST_OS == 'linux':
        if success:
            icon = 'dialog-information'
        else:
            icon = 'dialog-error'
        command = "notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
    elif HOST_OS == 'win32':
        if success:
            icon = 'info'
        else:
            icon = 'error'
        command = (
            "powershell -command \""
            "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
            "| Out-Null;"
            "[reflection.assembly]::loadwithpartialname('System.Drawing')"
            "| Out-Null;"
            "$n = new-object system.windows.forms.notifyicon;"
            "$n.icon = [system.drawing.systemicons]::information;"
            "$n.visible = $true;"
            "$n.showballoontip(%d, '%s', '%s', "
            "[system.windows.forms.tooltipicon]::%s);\"") % (
                5000,  # Notification stays on for this many milliseconds
                message,
                title,
                icon)

    if command:
        # Ignore return code, if this command fails, it doesn't matter.
        os.system(command)


def GenerateBuildfilesIfNeeded():
    if os.path.exists(utils.GetBuildDir(HOST_OS)):
        return True
    command = [
        'python',
        os.path.join(DART_ROOT, 'tools', 'generate_buildfiles.py')
    ]
    print("Running " + ' '.join(command))
    process = subprocess.Popen(command)
    process.wait()
    if process.returncode != 0:
        print("Tried to generate missing buildfiles, but failed. "
              "Try running manually:\n\t$ " + ' '.join(command))
        return False
    return True


def RunGNIfNeeded(out_dir, target_os, mode, arch, use_nnbd):
    if os.path.isfile(os.path.join(out_dir, 'args.gn')):
        return
    gn_os = 'host' if target_os == HOST_OS else target_os
    gn_command = [
        'python',
        os.path.join(DART_ROOT, 'tools', 'gn.py'),
        '-m',
        mode,
        '-a',
        arch,
        '--os',
        gn_os,
        '-v',
    ]
    if use_nnbd:
        gn_command.append('--nnbd')

    process = subprocess.Popen(gn_command)
    process.wait()
    if process.returncode != 0:
        print("Tried to run GN, but it failed. Try running it manually: \n\t$ "
              + ' '.join(gn_command))


def UseGoma(out_dir):
    args_gn = os.path.join(out_dir, 'args.gn')
    return 'use_goma = true' in open(args_gn, 'r').read()


# Try to start goma, but don't bail out if we can't. Instead print an error
# message, and let the build fail with its own error messages as well.
goma_started = False


def EnsureGomaStarted(out_dir):
    global goma_started
    if goma_started:
        return True
    args_gn_path = os.path.join(out_dir, 'args.gn')
    goma_dir = None
    with open(args_gn_path, 'r') as fp:
        for line in fp:
            if 'goma_dir' in line:
                words = line.split()
                goma_dir = words[2][1:-1]  # goma_dir = "/path/to/goma"
    if not goma_dir:
        print('Could not find goma for ' + out_dir)
        return False
    if not os.path.exists(goma_dir) or not os.path.isdir(goma_dir):
        print('Could not find goma at ' + goma_dir)
        return False
    goma_ctl = os.path.join(goma_dir, 'goma_ctl.py')
    goma_ctl_command = [
        'python',
        goma_ctl,
        'ensure_start',
    ]
    process = subprocess.Popen(goma_ctl_command)
    process.wait()
    if process.returncode != 0:
        print(
            "Tried to run goma_ctl.py, but it failed. Try running it manually: "
            + "\n\t" + ' '.join(goma_ctl_command))
        return False
    goma_started = True
    return True


# Returns a tuple (build_config, command to run, whether goma is used)
def BuildOneConfig(options, targets, target_os, mode, arch):
    build_config = utils.GetBuildConf(mode, arch, target_os, options.nnbd)
    out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os, options.nnbd)
    using_goma = False
    # TODO(zra): Remove auto-run of gn, replace with prompt for user to run
    # gn.py manually.
    RunGNIfNeeded(out_dir, target_os, mode, arch, options.nnbd)
    command = ['ninja', '-C', out_dir]
    if options.verbose:
        command += ['-v']
    if UseGoma(out_dir):
        if options.no_start_goma or EnsureGomaStarted(out_dir):
            using_goma = True
            command += [('-j%s' % str(options.j))]
            command += [('-l%s' % str(options.l))]
        else:
            # If we couldn't ensure that goma is started, let the build start, but
            # slowly so we can see any helpful error messages that pop out.
            command += ['-j1']
    command += targets
    return (build_config, command, using_goma)


def RunOneBuildCommand(build_config, args):
    start_time = time.time()
    print(' '.join(args))
    process = subprocess.Popen(args, stdin=None)
    process.wait()
    if process.returncode != 0:
        NotifyBuildDone(build_config, success=False, start=start_time)
        return 1
    else:
        NotifyBuildDone(build_config, success=True, start=start_time)

    return 0


def RunOneGomaBuildCommand(args):
    try:
        print(' '.join(args))
        process = subprocess.Popen(args, stdin=None)
        process.wait()
        print(' '.join(args) + " done.")
        return process.returncode
    except KeyboardInterrupt:
        return 1


def Main():
    starttime = time.time()
    # Parse the options.
    parser = BuildOptions()
    (options, args) = parser.parse_args()
    if not ProcessOptions(options, args):
        parser.print_help()
        return 1
    # Determine which targets to build. By default we build the "all" target.
    if len(args) == 0:
        targets = ['all']
    else:
        targets = args

    if not GenerateBuildfilesIfNeeded():
        return 1

    # Build all targets for each requested configuration.
    configs = []
    for target_os in options.os:
        for mode in options.mode:
            for arch in options.arch:
                configs.append(
                    BuildOneConfig(options, targets, target_os, mode, arch))

    # Build regular configs.
    goma_builds = []
    for (build_config, args, goma) in configs:
        if args is None:
            return 1
        if goma:
            goma_builds.append(args)
        elif RunOneBuildCommand(build_config, args) != 0:
            return 1

    # Run goma builds in parallel.
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
    for r in results:
        if r != 0:
            return 1

    endtime = time.time()
    print("The build took %.3f seconds" % (endtime - starttime))
    return 0


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