#!/usr/bin/env python3
from pathlib import Path
import hashlib,json,re,datetime
P='gacmai_20260717_104203';R=Path('/data/video-pipeline/GacMaiAudio/project')/P;A=R/'artifacts'
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def fail(m):raise SystemExit(m)
story=A/'story_package_canonical.json';release=A/'story_release_manifest.json';status=R/'status.json'
for p in (story,release,status):
 if not p.exists():fail(f'missing {p.name}')
s=json.loads(story.read_text());rel=json.loads(release.read_text());st=json.loads(status.read_text());h=sha(story)
if rel.get('status')!='passed' or rel.get('story_sha256')!=h or rel.get('tts_authorized') is not True:fail('release manifest does not authorize exact story')
if st.get('story_sha256')!=h or st.get('tts_authorized') is not True or st.get('provider_spend_authorized') is not True:fail('status does not authorize exact story')
parts=s.get('parts',[])
if [x.get('part') for x in parts]!=list(range(1,13)) or any(len(x.get('paragraphs',[]))!=12 for x in parts):fail('story structure mismatch')
segments=[]
for part in parts:
 for idx,text in enumerate(part['paragraphs'],1):
  if not isinstance(text,str) or not text.strip():fail('empty narration paragraph')
  segments.append({'segment_id':f"P{part['part']:02d}D{idx:02d}",'part':part['part'],'paragraph':idx,'text':text.strip()})
if len(segments)!=144:fail('segment count mismatch')
narration='\n\n'.join(x['text'] for x in segments)+'\n';narration_sha=hashlib.sha256(narration.encode()).hexdigest();projection={'status':'passed','project_id':P,'title':s['title'],'voice':'Ngọc Huyền','story_sha256':h,'parts':12,'segments':segments,'segment_count':144,'narration_sha256':narration_sha,'word_count':len(re.findall(r'\b\w+\b',narration,re.UNICODE)),'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat()};raw=(json.dumps(projection,ensure_ascii=False,indent=2)+'\n').encode();(A/'tts_projection.json').write_bytes(raw);(A/'narration.txt').write_text(narration);receipt={'status':'passed','story_sha256':h,'projection_sha256':hashlib.sha256(raw).hexdigest(),'narration_sha256':narration_sha,'segment_count':144,'voice':'Ngọc Huyền'};(A/'tts_projection_receipt.json').write_text(json.dumps(receipt,ensure_ascii=False,indent=2)+'\n');print(json.dumps(receipt,ensure_ascii=False))
