#!/usr/bin/env python
#
# 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()
    execfile(filename, 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())
