#!/usr/bin/python
# Copyright 2018 the V8 project authors. All rights reserved.

'''
python %prog -c <command> [options]

Local benchmark runner.
The -c option is mandatory.
'''

# for py2/py3 compatibility
from __future__ import print_function

import math
from optparse import OptionParser
import os
import re
import subprocess
import sys
import time

def GeometricMean(numbers):
  log = sum([math.log(n) for n in numbers])
  return math.pow(math.e, log / len(numbers))


class BenchmarkSuite(object):

  def __init__(self, name):
    self.name = name
    self.results = {}
    self.tests = []
    self.avgresult = {}
    self.sigmaresult = {}
    self.numresult = {}
    self.kClassicScoreSuites = ["SunSpider", "Kraken"]
    self.kGeometricScoreSuites = ["Octane"]


  def RecordResult(self, test, result):
    if test not in self.tests:
      self.tests += [test]
      self.results[test] = []
    self.results[test] += [int(result)]

  def ThrowAwayWorstResult(self, results):
    if len(results) <= 1: return
    if self.name in self.kClassicScoreSuites:
      results.pop()
    elif self.name in self.kGeometricScoreSuites:
      del results[0]

  def ProcessResults(self, opts):
    for test in self.tests:
      results = self.results[test]
      results.sort()
      self.ThrowAwayWorstResult(results)
      mean = sum(results) * 1.0 / len(results)
      self.avgresult[test] = mean
      sigma_divisor = len(results) - 1
      if sigma_divisor == 0:
        sigma_divisor = 1
      self.sigmaresult[test] = math.sqrt(
          sum((x - mean) ** 2 for x in results) / sigma_divisor)
      self.numresult[test] = len(results)
      if opts.verbose:
        if not test in ["Octane"]:
          print("%s,%.1f,%.2f,%d" %
              (test, self.avgresult[test],
               self.sigmaresult[test], self.numresult[test]))

  def ComputeScoreGeneric(self):
    self.score = 0
    self.sigma = 0
    for test in self.tests:
      self.score += self.avgresult[test]
      self.sigma += self.sigmaresult[test]
      self.num = self.numresult[test]

  def ComputeScoreV8Octane(self, name):
    # The score for the run is stored with the form
    # "Octane-octane2.1(Score): <score>"
    found_name = ''
    for s in self.avgresult.keys():
      if re.search("^Octane", s):
        found_name = s
        break

    self.score = self.avgresult[found_name]
    self.sigma = 0
    for test in self.tests:
      self.sigma += self.sigmaresult[test]
      self.num = self.numresult[test]
    self.sigma /= len(self.tests)

  def ComputeScore(self):
    if self.name in self.kClassicScoreSuites:
      self.ComputeScoreGeneric()
    elif self.name in self.kGeometricScoreSuites:
      self.ComputeScoreV8Octane(self.name)
    else:
      print("Don't know how to compute score for suite: '%s'" % self.name)

  def IsBetterThan(self, other):
    if self.name in self.kClassicScoreSuites:
      return self.score < other.score
    elif self.name in self.kGeometricScoreSuites:
      return self.score > other.score
    else:
      print("Don't know how to compare score for suite: '%s'" % self.name)


class BenchmarkRunner(object):
  def __init__(self, args, current_directory, opts):
    self.best = {}
    self.second_best = {}
    self.args = args
    self.opts = opts
    self.current_directory = current_directory
    self.outdir = os.path.join(opts.cachedir, "_benchmark_runner_data")

  def Run(self):
    if not os.path.exists(self.outdir):
      os.mkdir(self.outdir)

    self.RunCommand()
    # Figure out the suite from the command line (heuristic) or the current
    # working directory.
    teststr = opts.command.lower() + " " + self.current_directory.lower()
    if teststr.find('octane') >= 0:
      suite = 'Octane'
    elif teststr.find('sunspider') >= 0:
      suite = 'SunSpider'
    elif teststr.find('kraken') >= 0:
      suite = 'Kraken'
    else:
      suite = 'Generic'

    self.ProcessOutput(suite)

  def RunCommand(self):
    for i in range(self.opts.runs):
      outfile = "%s/out.%d.txt" % (self.outdir, i)
      if os.path.exists(outfile) and not self.opts.force:
        continue
      print("run #%d" % i)
      cmdline = "%s > %s" % (self.opts.command, outfile)
      subprocess.call(cmdline, shell=True)
      time.sleep(self.opts.sleep)

  def ProcessLine(self, line):
    # Octane puts this line in before score.
    if line == "----":
      return (None, None)

    # Kraken or Sunspider?
    g = re.match("(?P<test_name>\w+(-\w+)*)\(RunTime\): (?P<score>\d+) ms\.", \
        line)
    if g == None:
      # Octane?
      g = re.match("(?P<test_name>\w+): (?P<score>\d+)", line)
      if g == None:
        g = re.match("Score \(version [0-9]+\): (?P<score>\d+)", line)
        if g != None:
          return ('Octane', g.group('score'))
        else:
          # Generic?
          g = re.match("(?P<test_name>\w+)\W+(?P<score>\d+)", line)
          if g == None:
            return (None, None)
    return (g.group('test_name'), g.group('score'))

  def ProcessOutput(self, suitename):
    suite = BenchmarkSuite(suitename)
    for i in range(self.opts.runs):
      outfile = "%s/out.%d.txt" % (self.outdir, i)
      with open(outfile, 'r') as f:
        for line in f:
          (test, result) = self.ProcessLine(line)
          if test != None:
            suite.RecordResult(test, result)

    suite.ProcessResults(self.opts)
    suite.ComputeScore()
    print(("%s,%.1f,%.2f,%d " %
        (suite.name, suite.score, suite.sigma, suite.num)), end='')
    if self.opts.verbose:
      print("")
    print("")


if __name__ == '__main__':
  parser = OptionParser(usage=__doc__)
  parser.add_option("-c", "--command", dest="command",
                    help="Command to run the test suite.")
  parser.add_option("-r", "--runs", dest="runs", default=4,
                    help="Number of runs")
  parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                    default=False, help="Print results for each test")
  parser.add_option("-f", "--force", dest="force", action="store_true",
                    default=False,
                    help="Force re-run even if output files exist")
  parser.add_option("-z", "--sleep", dest="sleep", default=0,
                    help="Number of seconds to sleep between runs")
  parser.add_option("-d", "--run-directory", dest="cachedir",
                    help="Directory where a cache directory will be created")
  (opts, args) = parser.parse_args()
  opts.runs = int(opts.runs)
  opts.sleep = int(opts.sleep)

  if not opts.command:
    print("You must specify the command to run (-c). Aborting.")
    sys.exit(1)

  cachedir = os.path.abspath(os.getcwd())
  if not opts.cachedir:
    opts.cachedir = cachedir
  if not os.path.exists(opts.cachedir):
    print("Directory " + opts.cachedir + " is not valid. Aborting.")
    sys.exit(1)

  br = BenchmarkRunner(args, os.getcwd(), opts)
  br.Run()
