#!/usr/bin/env python
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
# ==------------------------------------------------------------------------==#

import os
import glob
import re
import subprocess
import json
import datetime
import argparse
import urllib
import urllib2

parser = argparse.ArgumentParser()
parser.add_argument('benchmark_directory')
parser.add_argument('--runs', type=int, default=10)
parser.add_argument('--wrapper', default='')
parser.add_argument('--machine', required=True)
parser.add_argument('--revision', required=True)
parser.add_argument('--threads', action='store_true')
parser.add_argument('--url', help='The lnt server url to send the results to',
                    default='http://localhost:8000/db_default/v4/link/submitRun')
args = parser.parse_args()

class Bench:
    def __init__(self, directory, variant):
        self.directory = directory
        self.variant = variant
    def __str__(self):
        if not self.variant:
            return self.directory
        return '%s-%s' % (self.directory, self.variant)

def getBenchmarks():
    ret = []
    for i in glob.glob('*/response*.txt'):
        m = re.match('response-(.*)\.txt', os.path.basename(i))
        variant = m.groups()[0] if m else None
        ret.append(Bench(os.path.dirname(i), variant))
    return ret

def parsePerfNum(num):
    num = num.replace(b',',b'')
    try:
        return int(num)
    except ValueError:
        return float(num)

def parsePerfLine(line):
    ret = {}
    line = line.split(b'#')[0].strip()
    if len(line) != 0:
        p = line.split()
        ret[p[1].strip().decode('ascii')] = parsePerfNum(p[0])
    return ret

def parsePerf(output):
    ret = {}
    lines = [x.strip() for x in output.split(b'\n')]

    seconds = [x for x in lines if b'seconds time elapsed' in x][0]
    seconds = seconds.strip().split()[0].strip()
    ret['seconds-elapsed'] = parsePerfNum(seconds)

    measurement_lines = [x for x in lines if b'#' in x]
    for l in measurement_lines:
        ret.update(parsePerfLine(l))
    return ret

def run(cmd):
    try:
        return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
        print(e.output)
        raise e

def combinePerfRun(acc, d):
    for k,v in d.items():
        a = acc.get(k, [])
        a.append(v)
        acc[k] = a

def perf(cmd):
    # Discard the first run to warm up any system cache.
    run(cmd)

    ret = {}
    wrapper_args = [x for x in args.wrapper.split(',') if x]
    for i in range(args.runs):
        os.unlink('t')
        out = run(wrapper_args + ['perf', 'stat'] + cmd)
        r = parsePerf(out)
        combinePerfRun(ret, r)
    os.unlink('t')
    return ret

def runBench(bench):
    thread_arg = [] if args.threads else ['--no-threads']
    os.chdir(bench.directory)
    suffix = '-%s' % bench.variant if bench.variant else ''
    response = 'response' + suffix + '.txt'
    ret = perf(['../ld.lld', '@' + response, '-o', 't'] + thread_arg)
    ret['name'] = str(bench)
    os.chdir('..')
    return ret

def buildLntJson(benchmarks):
    start = datetime.datetime.utcnow().isoformat()
    tests = [runBench(b) for b in benchmarks]
    end = datetime.datetime.utcnow().isoformat()
    ret = {
        'format_version' : 2,
        'machine' : { 'name' : args.machine },
        'run' : {
            'end_time' : start,
            'start_time' : end,
            'llvm_project_revision': args.revision
        },
        'tests' : tests
    }
    return json.dumps(ret, sort_keys=True, indent=4)

def submitToServer(data):
    data2 = urllib.urlencode({ 'input_data' : data }).encode('ascii')
    urllib2.urlopen(urllib2.Request(args.url, data2))

os.chdir(args.benchmark_directory)
data = buildLntJson(getBenchmarks())
submitToServer(data)
