#! /usr/bin/python3

import sys
import getopt
import glob
import os
import re

usage_string = f"""
usage: {sys.argv[0]} -o <output folder> [-p <options>] [<source folder>]

Sets up a folder and Makefile to run all the tests from the source directory
under perf. Scans the .test files of the source directory and produces a
Makefile in the output directory that runs them and records execution
statistics in .perfstats files.

Options:
  -o <output directory>
    Specify the output directory, which will consist of a Makefile and (after
    testing) as set of .perfstats files.
  -p <options>
    Additional options to pass to perf. '-p "-r 1"' will test each program only
    once. Defaults to "--table -r 10". Using -p will override the default, so
    you really want to specify a "-r".
  <source directory>
    Where to look for .test files. Defaults to current directory.

Typical use:
  % cd /testsuite/O3
  % ../configure-perf.py -o perf-run-01
""".strip()

# Parse command-line arguments

opt, args = getopt.gnu_getopt(sys.argv[1:], "ho:p:", ["help"])
opt = dict(opt)

if len(sys.argv) == 1 or '-h' in opt or '--help' in opt:
    print(usage_string, file=sys.stderr)
    sys.exit(0)

if '-o' not in opt:
    print("error: please specify an output directory with -o", file=sys.stderr)
    sys.exit(1)

perfopt = opt.get('-p', "--table -r 10")
indir   = args[0] if args else '.'
outdir  = opt.get('-o')

# Create output directory and Makefile

try:
    os.mkdir(outdir)
except FileExistsError:
    pass

Makefile = open(os.path.join(outdir, "Makefile"), "w")

# Parse all .test files

tests = glob.glob(os.path.join(indir, '**', '*.test'), recursive=True)
pattern = re.compile(r'^RUN: (.*)$', re.MULTILINE)

target_all = ""
targets = ""

for file in tests:
    name = os.path.basename(file[:-5])
    # Takes a horrible amount of time, dunno why yet
    if name == "lua": continue

    out = f"{name}.perfstats"

    m = re.search(pattern, open(file, "r").read())
    if m is None:
        print(f"[{name}] ERROR: no run command found")

    command = m[1]

    target_all += f' {out}'

    targets += f'{out}:\n'
    targets += f"\t@ date '+%F %R:%S {name}'\n"
    targets += f'\t- perf stat {perfopt} -o {out} bash -c "{command}" ' + \
        '>/dev/null 2>&1\n\n'

print(f"all: {target_all}\n", file=Makefile)
print(targets, file=Makefile)
