"""Summarize raw measurements without excluding failed or slow runs."""
import argparse
from collections import defaultdict
import json
from pathlib import Path
import statistics

p = argparse.ArgumentParser()
p.add_argument('results', nargs='+', type=Path)
p.add_argument('--output', required=True, type=Path)
a = p.parse_args()
lines = ['Skirr prototype: local HTTP/1 comparison', '',
         'One worker pinned to CPU 0; wrk on CPUs 4-7; identical apps and Python.',
         'Access logs, request IDs, compression and response caches disabled; lifespan recorded per matrix.',
         'Server allocator/GC defaults retained; Skirr does not alter application GC policy.',
         'Medians of repeated runs; counts, duration and warmup are recorded per matrix.',
         'Temporary performance-profile hold for final matrices; CPU clocks sampled per run.',
         'No TLS, HTTP/2, WebSockets or pipelining in the throughput workload.',
         'Exact body/status checked before/after each run, not on every wrk response.',
         'P99 below is median per-run wrk P99, not a pooled percentile.',
         'Timeout semantics follow the recorded generator; all counters are retained.',
         'These measurements do not establish production readiness or general superiority.', '']
total_requests = 0
for path in a.results:
    d = json.loads(path.read_text())
    config = d['metadata']['configuration']
    lines += [f"Connections: {config['connections']}; repeats: {config['repeats']}; duration: {config['duration']}s; warmup: {config['warmup']}s; offered rate: {config.get('rate') or 'unlimited'}; lifespan: {config.get('lifespan', 'off')}",
              'Power profile: ' + str(d['metadata'].get('power_profile', 'not recorded')),
              'Versions: ' + json.dumps(d['metadata']['versions'], sort_keys=True),
              'Workload          Server          Req/s     P99 ms   IO failures  Timeouts  HTTP errors   PSS MiB   RPS range   P99 range ms']
    groups = defaultdict(list)
    for row in d['runs']:
        groups[row['workload'], row['server']].append(row)
        total_requests += row['requests']
    for (workload, server), rows in sorted(groups.items()):
        rate = statistics.median(r['requests_per_second'] for r in rows)
        p99 = statistics.median(r['p99_latency_ms'] for r in rows)
        errors = sum(sum(r['socket_error_detail'].get(k, 0) for k in ('connect', 'read', 'write')) for r in rows)
        timeout = sum(r['socket_error_detail'].get('timeout', 0) for r in rows)
        http = sum(r['non_2xx_3xx'] for r in rows)
        pss = statistics.median(r['peak_tree_pss_mib'] for r in rows)
        low, high = min(r['requests_per_second'] for r in rows), max(r['requests_per_second'] for r in rows)
        lines.append(f'{workload:17} {server:13} {rate:10,.0f} {p99:10.2f} {errors:11} {timeout:5} {http:13} {pss:9.1f} {low:,.0f}-{high:,.0f}   {min(r['p99_latency_ms'] for r in rows):.2f}-{max(r['p99_latency_ms'] for r in rows):.2f}')
    if any(row.get('server_frequency_khz') for row in d['runs']):
        lines += ['', 'Sampled server CPU clocks (MHz; median per-run mean, full observed range):']
        for server in sorted({row['server'] for row in d['runs']}):
            per_run = [[value / 1000 for sample in row.get('server_frequency_khz', []) for value in sample.values()]
                       for row in d['runs'] if row['server'] == server]
            per_run = [values for values in per_run if values]
            if per_run:
                all_values = [value for values in per_run for value in values]
                lines.append(f'{server:13} {statistics.median(statistics.mean(values) for values in per_run):.0f}; '
                             f'{min(all_values):.0f}-{max(all_values):.0f}')
    if any(server == 'skirr-before' for _, server in groups):
        lines += ['', 'Optimized Skirr change versus same-session saved baseline:']
        for workload in sorted({w for w, _ in groups}):
            rates = {server: statistics.median(r['requests_per_second'] for r in rows)
                     for (w, server), rows in groups.items() if w == workload}
            comparison = [f"{workload:17} {(rates['skirr']/rates['skirr-before']-1)*100:+.1f}%"]
            for peer, title in [('weft', 'Weft'), ('peregrine', 'Peregrine')]:
                if peer in rates:
                    comparison.append(f"versus {title} {(rates['skirr']/rates[peer]-1)*100:+.1f}%")
            lines.append('; '.join(comparison))
    if d['streaming']:
        lines += ['', 'Streaming: app waits 50ms after the first chunk; 20 sequential samples.']
    for row in d['streaming']:
        lines.append(f"{row['server']:10} first-byte {row['median_first_body_byte_ms']:.3f}ms; total {row['median_total_ms']:.3f}ms")
    lines += ['', f'Raw artifact: {path}', '']
lines += [f'Total completed requests across these comparisons: {total_requests:,}', '',
          'wrk histogram counter behavior: https://github.com/wg/wrk/blob/4.1.0/src/wrk.c#L301-L325',
          'wrk2 corrected fixed-rate histograms: https://github.com/giltene/wrk2/tree/44a94c17d8e6a0bac8559b53da76848e430cb7a7']
a.output.write_text('\n'.join(lines) + '\n')
print(a.output.read_text())
