#!/usr/bin/env python3
from pathlib import Path
import json,hashlib,subprocess,sys,datetime
P='gacmai_20260717_184527';R=Path('/data/video-pipeline/GacMaiAudio/project')/P;A=R/'artifacts';S=A/'scripts';OUT=A/'story_package_candidate_rev7.json';OUTLINE='6648cdf5473d3bf72c759726357ecfcf480feea01424569e866fced1abb6e7e9';EXPECTED=['0ec2c2315689efe32bb04c6757d0aef5e71d8b0764cd38be2dadcb9b73e257b3',None,'e91b009216147ab8caf3c8eb8847cd2369268b18a5e824cc49e6731ccc6404b1'];PARENT_MIDDLE='f1da8c43ed181d0c9b74c1ad6f3b43ae8ecc7d91b4ca1630617cd75f234ec7ec'
if len(sys.argv)!=4:raise SystemExit('usage: assemble_story_rev7 B1 B2_REV1 B3')
if OUT.exists():raise SystemExit('rev1 already exists')
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
paths=[Path(x) for x in sys.argv[1:]];ranges=[(1,4),(5,8),(9,12)];sources=[];parts=[]
for idx,(p,(a,b)) in enumerate(zip(paths,ranges)):
 h=sha(p)
 if EXPECTED[idx] and h!=EXPECTED[idx]:raise SystemExit(f'protected batch changed {p}')
 d=json.loads(p.read_text());cp=subprocess.run(['python3',str(S/'validate_batch.py'),str(p),str(a),str(b)],capture_output=True,text=True);v=json.loads(cp.stdout)
 if cp.returncode or v.get('status')!='passed' or d.get('outline_sha256')!=OUTLINE:raise SystemExit(f'batch gate failed {p}: {v}')
 parts.extend(d['parts']);sources.append({'path':str(p),'sha256':h,'part_range':[a,b],'parent_sha256':PARENT_MIDDLE if idx==1 else None})
story={'project_id':P,'title':'Mùa Nở Không Có Tên','outline_sha256':OUTLINE,'pov':'Nguyễn Lam Chi','named_characters':['Nguyễn Lam Chi','Trần Vĩnh Phúc','Lê Thu Nguyệt','Phạm Hữu Tường','Đỗ Khánh An','Vũ Minh Triết'],'revision':7,'parent_story_sha256':'7f86972011b9c87eab2516f345428956e2ef90813bef102dc67adcbe0e25a1a8','sources':sources,'parts':parts};OUT.write_text(json.dumps(story,ensure_ascii=False,indent=2)+'\n');h=sha(OUT);checks={}
cmds=[('validation',['python3',str(S/'validate_story.py'),str(OUT)]),('duplication',['python3',str(S/'audit_duplication.py'),str(OUT)]),('alignment',['python3',str(S/'audit_story_alignment.py'),str(OUT),str(A/'locked_outline_canonical.json')])]
for name,cmd in cmds:
 cp=subprocess.run(cmd,capture_output=True,text=True);checks[name]=json.loads(cp.stdout)
 if cp.returncode or checks[name].get('status')!='passed':
  rec={'status':'failed','story_sha256':h,'sources':sources,'checks':checks,'failed_gate':name};(A/'story_assembly_receipt_rev7.json').write_text(json.dumps(rec,ensure_ascii=False,indent=2)+'\n');print(json.dumps(rec,ensure_ascii=False));raise SystemExit(1)
rec={'status':'passed','story_sha256':h,'parent_story_sha256':story['parent_story_sha256'],'sources':sources,'checks':checks,'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat()};(A/'story_assembly_receipt_rev7.json').write_text(json.dumps(rec,ensure_ascii=False,indent=2)+'\n');print(json.dumps(rec,ensure_ascii=False))
