"""Analyze a VPX link-adapter capture (emulator/vpxlog.txt) from the Phase 1
logging device: summarize the access pattern, reconstruct the outbound byte
stream, and check it against the transputer monitor / i860 renderer files.

Usage:
    python analyze_capture.py [vpxlog.txt] [image_dir]
"""
import sys, os
from collections import OrderedDict

log_path = sys.argv[1] if len(sys.argv) > 1 else "vpxlog.txt"
image_dir = sys.argv[2] if len(sys.argv) > 2 else "image"

events = []          # (seq, dir, reg, value, run)
sent = bytearray()   # bytes written to outputData, in order
for line in open(log_path):
    line = line.strip()
    if not line or line.startswith("#"):
        continue
    parts = line.split()
    seq, d, reg, val = parts[0], parts[1], parts[2], parts[3]
    run = int(parts[4][1:]) if len(parts) > 4 and parts[4].startswith("x") else 1
    events.append((seq, d, reg, int(val, 16), run))
    if d == "W" and reg == "outputData":
        sent.extend([int(val, 16)] * run)

# access summary
counts = OrderedDict()
for _, d, reg, _, run in events:
    counts[(d, reg)] = counts.get((d, reg), 0) + run
print("=== access summary (run-length expanded) ===")
for (d, reg), n in sorted(counts.items(), key=lambda x: -x[1]):
    print(f"  {d}  {reg:<13} {n}")

# reset preamble (writes before the first outputData byte)
print("\n=== reset preamble (up to first payload byte) ===")
for seq, d, reg, val, run in events:
    if d == "W" and reg == "outputData":
        break
    print(f"  {seq}  {d}  {reg:<13} 0x{val:02X}" + (f"  x{run}" if run > 1 else ""))

print(f"\n=== outbound stream: {len(sent)} bytes ===")

def match(name):
    p = os.path.join(image_dir, name)
    if not os.path.exists(p):
        return f"  {name}: (not found)"
    data = open(p, "rb").read()
    if bytes(sent) == data:
        return f"  {name}: {len(data)} bytes  EXACT MATCH (whole stream)"
    if bytes(sent[:len(data)]) == data:
        return f"  {name}: {len(data)} bytes  MATCHES stream prefix (stream continues)"
    # first difference
    for i, (a, b) in enumerate(zip(sent, data)):
        if a != b:
            return f"  {name}: {len(data)} bytes  differs at offset {i} (sent 0x{a:02X} vs 0x{b:02X})"
    return f"  {name}: {len(data)} bytes  (stream is a prefix of file)"

print("=== compare outbound stream to boot files ===")
for f in ("VRENDMON.BTL", "VRNOSTEX.MNG", "VREND.MNG"):
    print(match(f))

if sent[:1]:
    n = sent[0]
    print(f"\n=== transputer boot-from-link ===")
    print(f"  first byte 0x{sent[0]:02X} ({sent[0]}) = primary-bootstrap length "
          f"(a standard bootable .BTL transputer image)")
