#!/usr/bin/env bash
#
# Canonical benchmark harness for layover.
#
# Parameters are hardcoded per mode. Do not override them and then
# compare to other runs — that is lying with numbers.
#
# Modes:
#   full        Balanced benchmark (CI default). Tests everything.
#   throughput  Stress bulk transfer + TLS crypto. Large data, high concurrency.
#   latency     Stress connection setup + interactive. Many round-trips, many connections.
#   compare     Run 'full', then diff against bench/results/baseline.json.
#
set -euo pipefail

MODE="${1:-full}"
OUTPUT="${2:-bench/results/latest.json}"

run_bench() {
    local bytes="$1" rounds="$2" concurrency="$3" output="$4"
    cargo run --release -- bench \
        --bytes "$bytes" \
        --latency-rounds "$rounds" \
        --concurrency "$concurrency" \
        --output "$output"
}

case "$MODE" in
    full)
        # Balanced — matches CI exactly. The canonical comparable benchmark.
        echo "=== layover bench: full (CI canonical) ==="
        echo "bytes=10MB latency_rounds=1000 concurrency=1,10,50,100"
        echo ""
        run_bench 10485760 1000 "1,10,50,100" "$OUTPUT"
        ;;

    throughput)
        # Stress bulk transfer and crypto. 200MB per stream test,
        # high concurrency to saturate CPU.
        echo "=== layover bench: throughput ==="
        echo "bytes=200MB latency_rounds=100 concurrency=1,10,50,100,200"
        echo ""
        run_bench 209715200 100 "1,10,50,100,200" "$OUTPUT"
        ;;

    latency)
        # Stress connection setup and interactive round-trips.
        # Small data, many rounds, many short-lived connections.
        echo "=== layover bench: latency ==="
        echo "bytes=1MB latency_rounds=5000 concurrency=1,10,50,100"
        echo ""
        run_bench 1048576 5000 "1,10,50,100" "$OUTPUT"
        ;;

    compare)
        BASELINE="bench/results/baseline.json"
        if [ ! -f "$BASELINE" ]; then
            echo "error: no baseline at $BASELINE"
            echo "create one: bench/run.sh full bench/results/baseline.json"
            exit 1
        fi

        echo "=== layover bench: full (comparing to baseline) ==="
        echo ""
        run_bench 10485760 1000 "1,10,50,100" "$OUTPUT"

        echo ""
        echo "=== comparison ==="
        python3 -c "
import json

b = json.load(open('$BASELINE'))
c = json.load(open('$OUTPUT'))

def fmt(v):
    if v >= 1000: return f'{v/1024:.1f} GB/s'
    return f'{v:.0f} MB/s'

def pct(old, new):
    if old == 0: return '  n/a'
    d = (new/old - 1) * 100
    return f'{d:+.0f}%'

print(f'baseline: {b[\"git_rev\"]}  current: {c[\"git_rev\"]}')
print()

header = f'{\"workload\":20s} {\"baseline relay\":>15s} {\"current relay\":>15s} {\"change\":>8s}'
has_tls = any(w.get('relay_tls') for w in c['workloads'].values())
if has_tls:
    header += f'   {\"baseline tls\":>15s} {\"current tls\":>15s} {\"change\":>8s}'
print(header)
print('-' * len(header))

for name in b['workloads']:
    bw = b['workloads'][name]
    cw = c['workloads'][name]
    br = bw['relay']['throughput_mbps']
    cr = cw['relay']['throughput_mbps']
    line = f'{name:20s} {fmt(br):>15s} {fmt(cr):>15s} {pct(br, cr):>8s}'

    bt = bw.get('relay_tls', {}).get('throughput_mbps')
    ct = cw.get('relay_tls', {}).get('throughput_mbps')
    if has_tls:
        if bt is not None and ct is not None:
            line += f'   {fmt(bt):>15s} {fmt(ct):>15s} {pct(bt, ct):>8s}'
        elif ct is not None:
            line += f'   {\"n/a\":>15s} {fmt(ct):>15s} {\"new\":>8s}'

    print(line)

print()
print('latency (relay p50 / p99):')
print(f'{\"workload\":20s} {\"baseline\":>20s} {\"current\":>20s}')
print('-' * 62)
for name in b['workloads']:
    bw = b['workloads'][name]
    cw = c['workloads'][name]
    bl = bw['relay']['latency']
    cl = cw['relay']['latency']
    print(f'{name:20s} {bl[\"p50_us\"]:>8d}us / {bl[\"p99_us\"]:<8d}us {cl[\"p50_us\"]:>8d}us / {cl[\"p99_us\"]:<8d}us')
"
        ;;

    *)
        echo "usage: bench/run.sh <mode> [output.json]"
        echo ""
        echo "modes:"
        echo "  full        balanced benchmark (CI default, canonical for comparison)"
        echo "  throughput  stress bulk transfer + TLS crypto (200MB, high concurrency)"
        echo "  latency     stress connection setup + interactive (5000 rounds)"
        echo "  compare     run 'full', diff against bench/results/baseline.json"
        exit 1
        ;;
esac
