#!/usr/bin/env python3
#
# Copyright (c) 2011, 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.

# Simple wrapper for running benchmarks.

import getopt
import optparse
import os
from os.path import join, dirname, realpath, abspath
import subprocess
import sys
import utils
import re

HOST_OS = utils.GuessOS()
HOST_CPUS = utils.GuessCpus()


# Returns whether 'bench' matches any element in the 'filt' list.
def match(bench, filt):
    bench = bench.lower()
    for element in filt:
        if element.search(bench):
            return True
    return False


def GetBenchmarkFile(path):
    benchmark_root_path = [dirname(sys.argv[0]), '..', '..'] + ['benchmarks']
    return realpath(os.path.sep.join(benchmark_root_path + path))


def ReadBenchmarkList(mode, path, core):
    filename = GetBenchmarkFile([path])
    benchmarks = dict()
    with open(filename) as infile:
        exec(infile.read(), benchmarks)
    if (mode == "release") and not core:
        return benchmarks['SUPPORTED_BENCHMARKS']
    else:
        return benchmarks['SUPPORTED_CORE_BENCHMARKS']


def BuildOptions():
    result = optparse.OptionParser()
    result.add_option(
        "-m",
        "--mode",
        help='Build variants (comma-separated).',
        metavar='[all,debug,release]',
        default='release')
    result.add_option(
        "-v",
        "--verbose",
        help='Verbose output.',
        default=False,
        action="store_true")
    result.add_option(
        "-c",
        "--core",
        help='Run only core benchmarks.',
        default=False,
        action="store_true")
    result.add_option(
        "--arch",
        help='Target architectures (comma-separated).',
        metavar='[all,ia32,x64,simarm,arm,dartc]',
        default=utils.GuessArchitecture())
    result.add_option(
        "--executable",
        help='Virtual machine to execute.',
        metavar='[dart, (path to dart binary)]',
        default=None)
    result.add_option(
        "-w",
        "--warmup",
        help='Only run the warmup period.',
        default=False,
        action="store_true")
    return result


def ProcessOptions(options):
    if options.arch == 'all':
        options.arch = 'ia32,x64,simarm,dartc'
    if options.mode == 'all':
        options.mode = 'debug,release'
    options.mode = options.mode.split(',')
    options.arch = options.arch.split(',')
    for mode in options.mode:
        if not mode in ['debug', 'release']:
            print("Unknown mode %s" % mode)
            return False
    for arch in options.arch:
        if not arch in ['ia32', 'x64', 'simarm', 'arm', 'dartc']:
            print("Unknown arch %s" % arch)
            return False
    return True


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


def GetDart(mode, arch, sanitizer):
    executable = [abspath(join(GetBuildRoot(mode, arch, sanitizer), 'dart'))]
    return executable


def Main():
    # Parse the options.
    parser = BuildOptions()
    (options, args) = parser.parse_args()
    if not ProcessOptions(options):
        parser.print_help()
        return 1

    chosen_benchmarks = ReadBenchmarkList(options.mode, 'BENCHMARKS',
                                          options.core)

    # Use arguments to filter the benchmarks.
    if len(args) > 0:
        filt = [re.compile(x.lower()) for x in args]
        chosen_benchmarks = [b for b in chosen_benchmarks if match(b[0], filt)]

    for mode in options.mode:
        for arch in options.arch:
            if options.executable is None:
                # Construct the path to the dart binary.
                executable = GetDart(mode, arch)
            else:
                executable = [options.executable]
            for benchmark, vmargs, progargs in chosen_benchmarks:
                command = executable
                command = command + [
                    GetBenchmarkFile([benchmark, 'dart', benchmark + '.dart']),
                ]
                if options.verbose:
                    print(' '.join(command))
                subprocess.call(command)
    return 0


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