#!/usr/bin/env python
import os, re, subprocess, signal, sys, tempfile, time, math

def fail():
  print "usage: " + sys.argv[0] + " <suite>"
  print ""
  print "Supported bench suites:"
  print "  * All: Reproduces bench/README.md"
  print "  * Quick: Lightweight subset of All that should be used for development"
  print "  * LSP: Another subset of All that can used for development"
  sys.exit(1)
if len(sys.argv) != 2: fail()
suite = sys.argv[1]
supported_suites = ["All", "Quick", "LSP"]
if not suite in supported_suites: fail()

def check_exists(path):
  if not os.path.exists(path): raise Exception(path + " does not exist")
  return path
binary_path = check_exists(os.path.abspath(sys.argv[0]))
repo_path = check_exists(os.path.dirname(os.path.dirname(binary_path)))

def call(command):
  print "Running " + command + "..."
  try:
    code = subprocess.call(command, shell = True, cwd = repo_path)
    if code != 0: raise Exception(command + " exited with code " + str(code))
  except KeyboardInterrupt:
    sys.exit(1)
start = time.time()
_, sbt_bench_log_path = tempfile.mkstemp(prefix = "sbt_bench" + suite + "_")
call("sbt bench" + suite + " | tee " + sbt_bench_log_path)
end = time.time()
print ""
print "Benchmarks completed in {0:.3f} ms".format(end - start)
print ""

rows = []
rows.append(("Benchmark", "Mode", "Cnt", "Score"))
lengths = [0] * 255
first = False
firstOps = -1
with open(sbt_bench_log_path, "r") as sbt_bench_log:
  for line in sbt_bench_log:
    m1 = re.search("(?:0m)?(\w+)\.run\s+(\w+)\s+(\d+)\s+(.*?\s+ms/op)", line)
    m2 = re.search("(?:0m)?(\w+)\.run\s+(?:.*?)\s+(\w+)\s+(\d+)\s+(.*?\s+ms/op)", line)
    m = m1 or m2
    if m:
      row = m.groups()
      for j, cell in enumerate(row): lengths[j] = max(len(cell), lengths[j])
      ops = float(re.search("(\d+.\d+)", row[3]).groups()[0])
      if not first:
        firstOps = ops
        first = True
      else:
        overhead = "(+ {}%)".format(int(math.ceil((ops / firstOps - 1) * 100)))
        row = row + (overhead, )
      rows.append(row)

for row in rows:
  for i, cell in enumerate(row):
    fmt = "{0:<" + str(lengths[i] + 2) + "}"
    text = cell.replace("  ", " ")
    sys.stdout.write(fmt.format(text))
  sys.stdout.write("\n")
