"""Finalize the verification of one search part: read all chunk results, re-verify with the current
verifier every original box (leaf or empty) that left an unresolved sub-box, and write
<part>.final.json with the combined counts. Usage: python finalize_part.py par_j1_p0.json"""
import sys, json, glob, time
import numpy as np, verify4
if __name__=="__main__":
    fn=sys.argv[1]; base=fn.replace(".json","")
    verify4.init(); d=json.load(open(fn)); j=d["j"]; V=d["V"]; pat=list(verify4.bbC.PATS[j])
    items=d["empties"]+d["leaves"]; nch=(len(items)+1999)//2000
    done={}
    for cf in glob.glob(base+".vchunks*.jsonl"):
        for line in open(cf):
            r=json.loads(line); done[r["chunk"]]=r
    assert len(done)==nch, f"{len(done)}/{nch} chunks"
    S=dict(ok=0,unresolved=0,sub_empty=0,sub_leaf=0); worst=-1.0; bad=[]
    for r in done.values():
        for k in S: S[k]+=r[k]
        worst=max(worst,r["max_ub"]); bad+=sum(r["bad"],[])
    los=np.array([x["lo"] for x in items]); his=np.array([x["hi"] for x in items])
    orig=set()
    for b in bad:
        lo=np.array(b["lo"]); hi=np.array(b["hi"])
        orig.add(int(np.where(np.all(los<=lo,1)&np.all(his>=hi,1))[0][0]))
    t0=time.time(); re=dict(ok=0,unresolved=0,face=0); still=[]
    for k in sorted(orig):
        st,info=verify4.work((pat,V,items[k])); re[st]+=1; re["face"]+=info.get("face",0)
        worst=max(worst,info["max_ub"])
        if st!="ok": still.append(dict(index=k,box=items[k],unresolved=info["unresolved"]))
    out=dict(part=fn,j=j,V=V,items=len(items),chunks=S,reverified_originals=len(orig),reverify=re,
             unresolved_after=len(still),max_ub=worst,still=still)
    json.dump(out,open(base+".final.json","w"),default=str)
    print("FINALIZED",fn,"V=",V,"items",len(items),S,"reverified",len(orig),re,"unresolved_after",len(still),"max ub",worst,f"{time.time()-t0:.0f}s",flush=True)
