"""Summarize write_modes.rs JSON Lines, preserving paired samples and provenance.

Run on the benchmark machine:
python3 write-modes-report.py --samples write-modes.jsonl --engine-root . --output write-modes.json
"""
import argparse
from datetime import datetime, timezone
import hashlib
import json
from pathlib import Path
import platform
import random
import statistics
import subprocess


def command(*args):
    return subprocess.check_output(args, text=True).strip()


def percentile(values, fraction):
    values = sorted(values)
    position = (len(values) - 1) * fraction
    lower = int(position)
    upper = min(lower + 1, len(values) - 1)
    return values[lower] + (values[upper] - values[lower]) * (position - lower)


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--samples', type=Path, required=True)
    parser.add_argument('--engine-root', type=Path, required=True)
    parser.add_argument('--output', type=Path, required=True)
    args = parser.parse_args()
    root = args.engine_root.resolve()
    commit = command('git', '-C', str(root), 'rev-parse', 'HEAD')
    assert commit == command('git', '-C', str(root), 'rev-list', '-n', '1', 'v1.0.0')
    assert not command('git', '-C', str(root), 'diff', 'HEAD', '--', 'heather_db/src', 'Cargo.lock')
    rows = [json.loads(line) for line in args.samples.read_text().splitlines()]
    assert len(rows) == 120
    results = []
    rng = random.Random(20261105)
    for workload, label in [('single', 'One vector · one call'), ('individual_100', '100 vectors · individual calls'), ('batch_100', '100 vectors · one batch')]:
        modes = [[r for r in rows if r['workload'] == workload and r['competitive'] is mode] for mode in [True, False]]
        for group in modes:
            group.sort(key=lambda row: row['round'])
            assert [r['round'] for r in group] == list(range(20))
            assert [r['seed'] for r in group] == list(range(20261107, 20261127))
        competitive, plain = [[r['elapsedNs'] for r in group] for group in modes]
        assert all(t > 0 for t in competitive + plain)
        boot = [[], [], []]
        for _ in range(10000):
            indices = rng.choices(range(20), k=20)
            means = [statistics.mean(values[i] for i in indices) for values in [competitive, plain]]
            for distribution, value in zip(boot, [*means, means[0] / means[1]]):
                distribution.append(value)
        result = {'workload': workload, 'label': label}
        for name, values, distribution in zip(['competitive', 'plain'], [competitive, plain], boot[:2]):
            result[name] = {'meanNs': statistics.mean(values), 'mean95CiNs': [percentile(distribution, p) for p in [.025, .975]]}
        result['ratio'] = statistics.mean(competitive) / statistics.mean(plain)
        result['ratio95Ci'] = [percentile(boot[2], p) for p in [.025, .975]]
        results.append(result)
    harness = root / 'heather_db/examples/write_modes.rs'
    files = ['heather_db/src/write.rs', 'heather_db/src/collection.rs', 'heather_db/src/store.rs', 'Cargo.lock']
    report = {
        'date': datetime.now(timezone.utc).date().isoformat(),
        'engineVersion': '1.0.0', 'engineCommit': commit,
        'hardware': {'cpu': command('sysctl', '-n', 'machdep.cpu.brand_string'), 'memoryBytes': int(command('sysctl', '-n', 'hw.memsize')), 'os': f'macOS {command("sw_vers", "-productVersion")}', 'architecture': platform.machine()},
        'rustc': command('rustc', '--version'), 'build': 'cargo run --release --locked -p heather_db --example write_modes',
        'harnessSha256': hashlib.sha256(harness.read_bytes()).hexdigest(),
        'sourceHashes': {name: hashlib.sha256((root / name).read_bytes()).hexdigest() for name in files},
        'method': {'dimensions': 128, 'prefillObservations': 200, 'prefillMethod': 'one write_batch outside timing', 'precision': 'f64', 'durability': 'synchronous LMDB default', 'mapSizeMiB': 256, 'measuredPairsPerWorkload': 20, 'discardedWarmupPairsPerWorkload': 2, 'input': 'StdRng seeded normal unit vectors; same 300 vectors for both modes in each pair', 'modeOrder': 'competitive first on even rounds; plain first on odd rounds', 'timing': 'std::time::Instant around write calls only; input generation, setup, prefill, count inspection and teardown excluded', 'uncertainty': '10,000 paired bootstrap resamples; percentile 95% intervals for means and ratio of means; seed 20261105; not request p95'},
        'scope': 'Native vector-only calls on one developer machine, fresh temporary databases per sample. No HTTP, metadata, embeddings, sustained-throughput or large-scale claim. Equal observations do not imply equal location counts: competitive mode can consolidate observations. These are separate measurements from the Criterion suite.',
        'results': results, 'samples': rows,
    }
    args.output.write_text(json.dumps(report, indent=2) + '\n')
    for row in results:
        print(row['workload'], 'competitive / plain:', round(row['ratio'], 3), '95% CI', [round(x, 3) for x in row['ratio95Ci']])


if __name__ == '__main__':
    main()
