#!/usr/bin/env python3
"""Locate quiet gaps and accumulated edge offsets in the published GPIO captures.

Run from the extracted hardware-benchmark directory: python3 explain-timing.py
Quiet gaps are observations, not decoded protocol boundaries or root causes.
"""
import hashlib
import json
from pathlib import Path


def analyze(root):
    records = {}
    hashes = {}
    for name in ('hardware', 'simulation'):
        path = root / (name + '.json')
        hashes[path.name] = hashlib.sha256(path.read_bytes()).hexdigest()
        raw = json.loads(path.read_text())
        start = next(t for t, level in raw['w0']['edges'] if level == 1)
        records[name] = {
            wire: [(t - start, level) for t, level in raw[wire]['edges'] if t >= start]
            for wire in ('w0', 'w1')
        }
    hw, sim = records['hardware'], records['simulation']
    for wire in hw:
        if [v for _, v in hw[wire]] != [v for _, v in sim[wire]]:
            raise ValueError('Ordered levels differ; edge pairing is not valid')
    gaps = {}
    for name, record in records.items():
        timestamps = sorted(set(t for channel in record.values() for t, _ in channel))
        gaps[name] = [(a, b) for a, b in zip(timestamps, timestamps[1:]) if b - a > 1_000_000]
    if len(gaps['hardware']) != len(gaps['simulation']):
        raise ValueError('Quiet-gap counts differ; inspect traces before pairing')
    paired = []
    for h, s in zip(gaps['hardware'], gaps['simulation']):
        paired.append({
            'hardware_start_ns': h[0], 'hardware_end_ns': h[1],
            'simulation_start_ns': s[0], 'simulation_end_ns': s[1],
            'hardware_duration_ns': h[1] - h[0],
            'simulation_duration_ns': s[1] - s[0],
            'duration_delta_ns': (s[1] - s[0]) - (h[1] - h[0]),
            'offset_before_ns': s[0] - h[0], 'offset_after_ns': s[1] - h[1],
        })
    offsets = [s[0] - h[0] for h, s in zip(hw['w0'], sim['w0'])]
    index = max(range(len(offsets)), key=lambda i: abs(offsets[i]))
    return {
        'capture_sha256': hashes,
        'alignment': 'First falling D4 edge; nanoseconds',
        'quiet_gap_threshold_ns': 1_000_000,
        'quiet_gaps_in_time_order': paired,
        'largest_data_offset': {'edge_index_zero_based': index, 'offset_ns': offsets[index]},
        'root_cause_identified': False,
        'scope': 'Locates accumulated timing differences; does not isolate CPU, interrupt, logging, or scheduler costs.',
    }


if __name__ == '__main__':
    print(json.dumps(analyze(Path(__file__).resolve().parent), indent=2))
