#!/usr/bin/env python3

import argparse
import re
import statistics
import sys

import plotly
import tabulate

def parse_lnt(lines):
    """
    Parse lines in LNT format and return a dictionnary of the form:

        {
            'benchmark1': {
                'metric1': [float],
                'metric2': [float],
                ...
            },
            'benchmark2': {
                'metric1': [float],
                'metric2': [float],
                ...
            },
            ...
        }

    Each metric may have multiple values.
    """
    results = {}
    for line in lines:
        line = line.strip()
        if not line:
            continue

        (identifier, value) = line.split(' ')
        (name, metric) = identifier.split('.')
        if name not in results:
            results[name] = {}
        if metric not in results[name]:
            results[name][metric] = []
        results[name][metric].append(float(value))
    return results

def plain_text_comparison(benchmarks, baseline, candidate):
    """
    Create a tabulated comparison of the baseline and the candidate.
    """
    headers = ['Benchmark', 'Baseline', 'Candidate', 'Difference', '% Difference']
    fmt = (None, '.2f', '.2f', '.2f', '.2f')
    table = []
    for (bm, base, cand) in zip(benchmarks, baseline, candidate):
        diff = (cand - base) if base and cand else None
        percent = 100 * (diff / base) if base and cand else None
        row = [bm, base, cand, diff, percent]
        table.append(row)
    return tabulate.tabulate(table, headers=headers, floatfmt=fmt, numalign='right')

def create_chart(benchmarks, baseline, candidate):
    """
    Create a bar chart comparing 'baseline' and 'candidate'.
    """
    figure = plotly.graph_objects.Figure()
    figure.add_trace(plotly.graph_objects.Bar(x=benchmarks, y=baseline, name='Baseline'))
    figure.add_trace(plotly.graph_objects.Bar(x=benchmarks, y=candidate, name='Candidate'))
    return figure

def prepare_series(baseline, candidate, metric, aggregate=statistics.median):
    """
    Prepare the data for being formatted or displayed as a chart.

    Metrics that have more than one value are aggregated using the given aggregation function.
    """
    all_benchmarks = sorted(list(set(baseline.keys()) | set(candidate.keys())))
    baseline_series = []
    candidate_series = []
    for bm in all_benchmarks:
        baseline_series.append(aggregate(baseline[bm][metric]) if bm in baseline and metric in baseline[bm] else None)
        candidate_series.append(aggregate(candidate[bm][metric]) if bm in candidate and metric in candidate[bm] else None)
    return (all_benchmarks, baseline_series, candidate_series)

def main(argv):
    parser = argparse.ArgumentParser(
        prog='compare-benchmarks',
        description='Compare the results of two sets of benchmarks in LNT format.',
        epilog='This script requires the `tabulate` and the `plotly` Python modules.')
    parser.add_argument('baseline', type=argparse.FileType('r'),
        help='Path to a LNT format file containing the benchmark results for the baseline.')
    parser.add_argument('candidate', type=argparse.FileType('r'),
        help='Path to a LNT format file containing the benchmark results for the candidate.')
    parser.add_argument('--metric', type=str, default='execution_time',
        help='The metric to compare. LNT data may contain multiple metrics (e.g. code size, execution time, etc) -- '
             'this option allows selecting which metric is being analyzed. The default is "execution_time".')
    parser.add_argument('--output', '-o', type=argparse.FileType('w'), default=sys.stdout,
        help='Path of a file where to output the resulting comparison. Default to stdout.')
    parser.add_argument('--filter', type=str, required=False,
        help='An optional regular expression used to filter the benchmarks included in the comparison. '
             'Only benchmarks whose names match the regular expression will be included.')
    parser.add_argument('--format', type=str, choices=['text', 'chart'], default='text',
        help='Select the output format. "text" generates a plain-text comparison in tabular form, and "chart" '
             'generates a self-contained HTML graph that can be opened in a browser. The default is text.')
    args = parser.parse_args(argv)

    baseline = parse_lnt(args.baseline.readlines())
    candidate = parse_lnt(args.candidate.readlines())

    if args.filter is not None:
        regex = re.compile(args.filter)
        baseline = {k: v for (k, v) in baseline.items() if regex.search(k)}
        candidate = {k: v for (k, v) in candidate.items() if regex.search(k)}

    (benchmarks, baseline_series, candidate_series) = prepare_series(baseline, candidate, args.metric)

    if args.format == 'chart':
        figure = create_chart(benchmarks, baseline_series, candidate_series)
        plotly.io.write_html(figure, file=args.output)
    else:
        diff = plain_text_comparison(benchmarks, baseline_series, candidate_series)
        args.output.write(diff)
        args.output.write('\n')

if __name__ == '__main__':
    main(sys.argv[1:])
