#!/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
try:
    from urllib.parse import urlencode
    from urllib.request import urlopen, Request
except ImportError:
    from urllib import urlencode
    from urllib2 import urlopen, Request


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 = urlencode({ 'input_data' : data }).encode('ascii')
    urlopen(Request(args.url, data2))

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