#!/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_rev1.json';OUTLINE='6648cdf5473d3bf72c759726357ecfcf480feea01424569e866fced1abb6e7e9';EXPECTED=['02a7e0a958bbf1195edba0f30d6781dd48562d8b3fa4276e6b516552c5965027',None,'f6ae5b1c05bbcaa48c26ef9c9c0cf07ca653f981074ba8561076682ffcb043fd'];PARENT_MIDDLE='10fa37e411b6a6605be99aaa3a5aff92789ba8b77e1bbbf358b8c3642100f18b'
if len(sys.argv)!=4:raise SystemExit('usage: assemble_story_rev1 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':1,'parent_story_sha256':'f1b1e90e7000b482a11f7b0475b8091d697e3db70cc16928c4bbc3212d256938','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_rev1.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_rev1.json').write_text(json.dumps(rec,ensure_ascii=False,indent=2)+'\n');print(json.dumps(rec,ensure_ascii=False))
