"""Audit saved movies and traces without Flyvis, PyTorch, or importing run.py."""
import csv
import hashlib
import json
from pathlib import Path
import numpy as np

root = Path(__file__).resolve().parent
out = root / "results-v01"
plan = json.loads((root / "plan.json").read_text())
summary = json.loads((out / "summary.json").read_text())
manifest = json.loads((out / "manifest.json").read_text())
checks = []

def check(name, value):
    assert bool(value), name
    checks.append(name)

for name, record in manifest.items():
    p = out / name
    check("sha256:"+name, hashlib.sha256(p.read_bytes()).hexdigest() == record["sha256"])
    check("bytes:"+name, p.stat().st_size == record["bytes"])
check("frozen-plan", summary["plan_sha256"] == hashlib.sha256((root/"plan.json").read_bytes()).hexdigest())
raw = {n: np.load(out/(n+".npz"), allow_pickle=False) for n in ["moving","repeat","grey"]}
a,b,g = [raw[n]["responses"] for n in ["moving","repeat","grey"]]
labels = list(csv.DictReader((out/"stimulus-labels.csv").open()))
times = raw["moving"]["time"]
types = raw["moving"]["cell_types"].tolist()
check("24-movies", len(labels) == 24 and a.shape[0] == 24)
check("all-conditions-finite", all(np.isfinite(x[k]).all() for x in raw.values() for k in ["responses","stimulus","time"]))
check("integration-grid", np.allclose(np.diff(times), plan["stimulus"]["dt"], rtol=0, atol=1e-12))
check("same-input-repeated", np.array_equal(raw["moving"]["stimulus"], raw["repeat"]["stimulus"]))
repeat_diff=float(np.max(np.abs(a-b)))
check("repeat-metric", repeat_diff == summary["repeat_max_absolute_difference"])
check("repeat-criterion-recorded", (repeat_diff <= 1e-6) == summary["repeat_passed"])
check("control-uniform", np.all(raw["grey"]["stimulus"] == 0.5))
control_diff=float(np.max(np.abs(g-g[0:1])))
check("control-metric", control_diff == summary["grey_max_difference_across_labels"])
check("control-criterion-recorded", (control_diff <= 1e-6) == summary["grey_label_independence_passed"])
metrics = list(csv.DictReader((out/"metrics.csv").open()))
curves = list(csv.DictReader((out/"direction-curves.csv").open()))
check("8-prespecified-readouts", [x["cell_type"] for x in metrics] == plan["readouts"])
check("96-direction-peaks", len(curves)==96)
pre=np.flatnonzero(times<0)[-1]
mask=(times>=0)&(times<summary["motion_duration_seconds"])
passes=0
for row in metrics:
    cell=row["cell_type"]; ni=types.index(cell); intensity=1 if cell.startswith("T4") else 0
    peaks={}
    for s,label in enumerate(labels):
        if int(label["intensity"]) != intensity: continue
        angle=int(label["angle"])
        peak=float(max(float(a[s,t,ni]-a[s,pre,ni]) for t in np.flatnonzero(mask)))
        peaks[angle]=peak
        reported=next(float(x["peak"]) for x in curves if x["cell_type"]==cell and int(x["angle"])==angle)
        check(cell+":curve:"+str(angle), peak==reported)
    known=plan["known_directions_degrees"][cell]
    opposite=(known+180)%360
    observed=max(peaks, key=peaks.get)
    error=min((known-observed)%360,(observed-known)%360)
    check(cell+":angle", observed==int(row["observed_peak_direction"]) and error==int(row["angle_error"]))
    check(cell+":preferred-peak", peaks[known]==float(row["preferred_peak"]))
    check(cell+":opposite-peak", peaks[opposite]==float(row["opposite_peak"]))
    passed=peaks[known]>peaks[opposite] and error<=30
    check(cell+":criterion-recorded", passed==(row["passed"]=="True"))
    passes+=int(passed)
check("direction-total", passes==summary["direction_passed"])
check("no-parameter-change-recorded", summary["weights_unchanged"] and all(x==summary["parameter_sha_before"] for x in summary["parameter_sha_after_conditions"].values()))
receipt={"passed":True,"checks":len(checks),"files_hashed":len(manifest),"direction_criteria_passed":passes,"direction_criteria_total":8,"method":"Independent saved-data audit using NumPy only; no inference rerun and no biological or motor validation.","repeat_max_abs":repeat_diff,"control_max_label_difference":control_diff,"check_names":checks}
(out/"validation.json").write_text(json.dumps(receipt,indent=2)+"\n")
print(json.dumps({k:v for k,v in receipt.items() if k!="check_names"},indent=2))
