#!/usr/bin/env python

# Note: it doesn't matter what directory you invoke this in; it uses
# your SWIFT_BUILD_ROOT and SWIFT_SOURCE_ROOT settings, just like
# build-script

# Note2: To avoid expensive rebuilds, it's often better to develop
# this script somewhere outside the source tree and then move it back
# when your changes are finished.

import subprocess
import sys
import os
import re
import shutil
import argparse
from pipes import quote as shell_quote

HOME = os.environ['HOME']
SWIFT_SOURCE_ROOT = os.environ.get('SWIFT_SOURCE_ROOT', os.path.join(HOME, 'src', 's'))
SWIFT_BUILD_ROOT = os.environ.get('SWIFT_BUILD_ROOT', os.path.join(SWIFT_SOURCE_ROOT, 'build'))
VERBOSE = False

variantDir = os.path.join(SWIFT_BUILD_ROOT, 'Ninja-Release')
buildDir = os.path.join(variantDir, 'swift-macosx-x86_64')
binDir = os.path.join(buildDir, 'bin')
benchDir = os.path.join(variantDir, 'bench')
sourceDir = os.path.join(SWIFT_SOURCE_ROOT, 'swift')

import os

def print_call(*args, **kw):
    if isinstance(args[0], (str, unicode)):
        args = [args]
        
    print '$ ' + ' '.join(shell_quote(x) for x in args[0]) + '   # %r, %r' % (args[1:], kw)
    
def check_call(*args, **kw):
    print_call(*args, **kw)
    try:
        return subprocess.check_call(*args, **kw)
    except:
        print('failed command:', args, kw)
        sys.stdout.flush()
        raise
    
def check_output(*args, **kw):
    print_call(*args, **kw)
    try:
        return subprocess.check_output(*args, **kw)
    except:
        print('failed command:', args, kw)
        sys.stdout.flush()
        raise
    
def getTreeSha(treeish):
    return check_output(['git', 'show', treeish, '-s', '--format=%t'], cwd=sourceDir).rstrip()
    
def getWorkTreeSha():
    if check_output(['git', 'status', '--porcelain', '--untracked-files=no'], cwd=sourceDir) == '':
        return getTreeSha('HEAD')
        
    # Create a stash without updating the working tree
    stashId = check_output(['git', 'stash', 'create', 'benchmark stash'], cwd=sourceDir).rstrip()
    check_call(['git', 'update-ref', '-m', 'benchmark stash', 'refs/stash', stashId], cwd=sourceDir)
    sha = getTreeSha('stash@{0}')
    check_call(['git', 'stash', 'drop', '-q'], cwd=sourceDir)
    return sha
    
def buildBenchmarks(cacheDir, build_script_args):
    print('Building executables...')
    
    configVars = {'SWIFT_INCLUDE_BENCHMARKS':'TRUE', 'SWIFT_INCLUDE_PERF_TESTSUITE':'TRUE', 'SWIFT_STDLIB_BUILD_TYPE':'RelWithDebInfo', 'SWIFT_STDLIB_ASSERTIONS':'FALSE'}
    
    cmakeCache = os.path.join(buildDir, 'CMakeCache.txt')
    
    configArgs = ['-D%s=%s' % i for i in configVars.items()]
    
    # Ensure swift is built with the appropriate options
    if os.path.isfile(cmakeCache):
        check_call(['cmake', '.'] + configArgs, cwd=buildDir)

    check_call(
        [ os.path.join(sourceDir, 'utils', 'build-script'),
          '-R', '--no-assertions']
        + build_script_args)

    # Doing this requires copying or linking all the libraries to the
    # same executable-relative location.  Probably not worth it.
    # Instead we'll just run the executables where they're built and
    # cache the timings
    #
    # print('  Copying executables to cache directory %r...' % cacheDir)
    # for exe in exeNames:
    #    shutil.copy(os.path.join(binDir, exe), os.path.join(cacheDir, exe))
    print('done.')

def collectBenchmarks(exeNames, treeish = None, repeat = 3, build_script_args = []):
    treeSha = getWorkTreeSha() if treeish is None else getTreeSha(treeish)
    cacheDir = os.path.join(benchDir, treeSha)
    print('Collecting benchmarks for %s in %s ' % (treeish if treeish else 'working tree', cacheDir))
    
    if not os.path.isdir(cacheDir):
        os.makedirs(cacheDir)

    rebuilt = False
    for exe in exeNames:
        timingsFile = os.path.join(cacheDir, exe) + '.out'
        timingsText = ''
        if not os.path.exists(timingsFile):
            print('Missing timings file for %s' % exe)
            m = re.search(
                r'^\* (?:\(detached from (.*)\)|(.*))$',
                check_output(['git', 'branch'], cwd=sourceDir),
                re.MULTILINE
            )
            
            saveHead = m.group(1) or m.group(2)

            if not rebuilt:
                if treeish is not None:
                    check_call(['git', 'stash', 'save', '--include-untracked'], cwd=sourceDir)

                    try:
                        check_call(['git', 'checkout', treeish], cwd=sourceDir)
                        buildBenchmarks(cacheDir, build_script_args)
                    finally:
                        subprocess.call(['git', 'checkout', saveHead], cwd=sourceDir)
                        subprocess.call(['git', 'stash', 'pop'], cwd=sourceDir)
                else:
                    buildBenchmarks(cacheDir, build_script_args)
                    
                rebuilt = True
        else:
            timingsText = open(timingsFile).read()
            oldRepeat = timingsText.count('\nTotal')
            if oldRepeat < repeat:
                print('Only %s repeats in existing %s timings file' % (oldRepeat, exe))
                timingsText = ''
                
        if timingsText == '':
            print('Running new benchmarks...')
            for iteration in range(0, repeat):
                print('  %s iteration %s' % (exe, iteration))
                output = check_output(os.path.join(binDir, exe))
                print(output)
                timingsText += output
                
            open(timingsFile, 'w').write(timingsText)
            print('done.')
            
    return cacheDir

# Parse lines like this
# #,TEST,SAMPLES,MIN(ms),MAX(ms),MEAN(ms),SD(ms),MEDIAN(ms)
SCORERE=re.compile(r"(\d+),[ \t]*(\w+),[ \t]*([\d.]+),[ \t]*([\d.]+)")

# The Totals line would be parsed like this, but we ignore it for now.
TOTALRE=re.compile(r"()(Totals),[ \t]*([\d.]+),[ \t]*([\d.]+)")

KEYGROUP=2
VALGROUP=4

def parseFloat(word):
    try:
        return float(word)
    except:
        raise ScoreParserException("Expected float val, not "+word)

def getScores(fname):
    scores = {}
    runs = 0
    f = open(fname)
    try:
        for line in f:
            if VERBOSE: print "Parsing", line,
            m = SCORERE.match(line)
            if not m:
                continue

            if not m.group(KEYGROUP) in scores:
                scores[m.group(KEYGROUP)] = []
            scores[m.group(KEYGROUP)].append(parseFloat(m.group(VALGROUP)))
            if len(scores[m.group(KEYGROUP)]) > runs:
                runs = len(scores[m.group(KEYGROUP)])
    finally:
        f.close()
    return scores, runs

def compareScores(key, score1, score2, runs):
    row = [key]
    bestscore1 = None
    bestscore2 = None
    r = 0
    for score in score1:
        if not bestscore1 or score < bestscore1:
            bestscore1 = score
        row.append("%.2f" % score)
    for score in score2:
        if not bestscore2 or score < bestscore2:
            bestscore2 = score
        row.append("%.2f" % score)
        r += 1
    while r < runs:
        row.append("0.0")

    row.append("%.2f" % abs(bestscore1-bestscore2))
    Num=float(bestscore1)
    Den=float(bestscore2)
    row.append(("%.2f" % (Num/Den)) if Den > 0 else "*")
    return row

def compareTimingsFiles(file1, file2):
    scores1, runs1 = getScores(file1)
    scores2, runs2 = getScores(file2)
    runs = min(runs1, runs2)
    if VERBOSE: print scores1; print scores2
    keys = [f for f in set(scores1.keys() + scores2.keys())]
    keys.sort()
    if VERBOSE:
        print "comparing ", file1, "vs", file2, "=",
        print file1, "/", file2

    rows =  [["benchmark"]]
    for i in range(0,runs):
        rows[0].append("baserun%d" % i)
    for i in range(0,runs):
        rows[0].append("optrun%d" % i)
    rows[0] += ["delta", "speedup"]

    for key in keys:
        if not key in scores1:
            print key, "not in", file1
            continue
        if not key in scores2:
            print key, "not in", file2
            continue
        rows.append(compareScores(key, scores1[key], scores2[key], runs))
        
    widths = []
    for row in rows:
        for n, x in enumerate(row):
            while n >= len(widths):
                widths.append(0)
            if len(x) > widths[n]:
                widths[n] = len(x)
    for row in rows:
        for n, x in enumerate(row):
            if n != 0:
                print ',',
            print ((widths[n] - len(x)) * ' ') + x,
        print ''

def checkAndUpdatePerfTestSuite(sourceDir):
    """Check that the performance testsuite directory is in its appropriate
       location and attempt to update it to ToT."""
    # Compute our benchmark directory name.
    benchdir = os.path.join(sourceDir, 'benchmark', 'PerfTestSuite')

    # If it's not there, clone it on demand.
    if not os.path.isdir(benchdir):
        check_call(
            [
                'git', 'clone',
            ])

    # Make sure that our benchdir has a .git directory in it. This will ensure
    # that users update to the new repository location. We could do more in
    # depth checks, but this is meant just as a simple sanity check for careless
    # errors.
    gitdir = os.path.join(benchdir, '.git')
    if not os.path.exists(gitdir):
        raise RuntimeError("PerfTestSuite dir is not a .git repo?!")

    # We always update the benchmarks to ToT.
    check_call(['git', 'pull', 'origin', 'master'], cwd=benchdir)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Show performance improvements/regressions in your Git working tree state')
    parser.add_argument('-r', '--repeat', dest='repeat', metavar='int', default=1, type=int,
                        help='number of times to repeat each test')
    parser.add_argument('-O', dest='optimization', choices=('3', 'unchecked', 'none'),
                        action='append', help='Optimization levels to test')
    parser.add_argument(dest='baseline', nargs='?', metavar='tree-ish', default='origin/master',
                        help='the baseline Git commit to compare with.')
    parser.add_argument(dest='build_script_args', nargs=argparse.REMAINDER, metavar='build-script-args', default=[]
                        help='additional arguments to build script, e.g. -- --distcc --build-args=-j30')
    args = parser.parse_args()

    optimization = args.optimization or ['3']
    exeNames = ['PerfTests_O' + ('' if x == '3' else x) for x in optimization]

    # Update PerfTests bench to ToT. If it does not exist, throw an error.
    #
    # TODO: This name sucks.
    checkAndUpdatePerfTestSuite(sourceDir)

    workCacheDir = collectBenchmarks(exeNames, tree_ish=None, repeat=args.repeat, build_script_args=args.build_script_args)    
    baselineCacheDir = collectBenchmarks(exeNames, tree_ish=args.baseline, repeat=args.repeat, build_script_args=args.build_script_args)
    
    if baselineCacheDir == workCacheDir:
        print('No changes between work tree and %s; nothing to compare.' % args.baseline)
    else:
        for exe in exeNames:
            print '=' * 20, exe, '=' * 20
            timingsFileName = exe + '.out'
            compareTimingsFiles(
                os.path.join(baselineCacheDir, timingsFileName),
                os.path.join(workCacheDir, timingsFileName)
            )
