#!/usr/bin/env python
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ==------------------------------------------------------------------------==#

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)
