#!/usr/bin/env python3
"""OBSERVABILITY: confere se cada CAMADA realmente sobreviveu no corte final. Pega o bug-classe de
'camada aplicada some num estágio posterior' (ex: judge engolido pela emoção). Roda após cada apply.

  ./venv/bin/python verify.py UNI5
"""
import json,sys,bisect
import vlib as V
END=999999

def cam_at(cps,F):
    cfr=[c["frame"] for c in cps]; i=bisect.bisect_right(cfr,F)-1
    return cps[max(0,i)]["angle"]

def frac_cam(cps,f0,f1,ang):
    """fração do span [f0,f1] que mostra `ang`."""
    tot=hit=0
    for f in range(int(f0),int(f1),5):
        tot+=1; hit+= (cam_at(cps,f)==ang)
    return hit/max(1,tot)

def stage_trace(span_f0,span_f1):
    """re-roda unified capturando o ângulo no span após cada estágio (acha QUEM engoliu)."""
    src=open(__import__("os").path.join(__import__("os").path.dirname(__file__), "unified.py")).read()
    marks={}
    for stage,marker in [("3.5-judge","# 4. clean"),("4-clean","# 5. emoção"),
                         ("5-emocao","# 6. settle"),("6-settle","cps=to_cps(log)")]:
        ns={}
        try:
            exec(src.split(marker)[0],ns)
            log=ns.get("log")
            if log:
                mid=(span_f0+span_f1)//2
                a=next((c for s,e,c in log if s<=mid<e),None)
                marks[stage]=a
        except Exception as ex:
            marks[stage]=f"err"
    return marks

if __name__=="__main__":
    name=sys.argv[1] if len(sys.argv)>1 else "UNI5"
    cps=sorted(json.load(open(f"versions/{name}.json"))["cutpoints"],key=lambda c:c["frame"])
    COV=V.coverage()
    print(f"=== AUDITORIA {name} ===\n")
    # 1. CAMADA JUDGE sobreviveu?
    sw=json.load(open("judge_switches_ok.json"))
    ok=swallowed=0
    fails=[]
    for v in sw:
        if "f0" not in v: continue
        ang=v["to_cam"]; f=frac_cam(cps,v["f0"],v["f1"],ang)
        if f>=0.5: ok+=1
        else:
            swallowed+=1; fails.append(v)
    print(f"JUDGE: {ok}/{ok+swallowed} switches sobreviveram | {swallowed} ENGOLIDOS")
    for v in fails:
        got=cam_at(cps,(v['f0']+v['f1'])//2)
        tr=stage_trace(v['f0'],v['f1'])
        print(f"  ❌ {v['tc']} esperado cam{v['to_cam']} got cam{got} | trace por estágio: {tr}")
    print(f"\nINTEGRIDADE CAMADA = {ok/max(1,ok+swallowed)*100:.0f}%")
