#!/usr/bin/env python3
from __future__ import annotations
import datetime as dt,hashlib,json,os,subprocess,sys
from pathlib import Path
ROOT=Path('/data/video-pipeline/HaTramAudio/project/018-Hon-Uoc-Khong-Duoc-Phep-Yeu');PROJECT=ROOT.name;RUN='run-20260721T040505Z-cd9f944a';OWNER='zoro'
CANON='d12e1733f81bf173b5db789b0028a0be478d0d2e565c05a91e236c95cd33bd78';TTS='1f78d70445770dea08b5690880a53bdff83cdeb7ca0e735f93510ad6edd0de79'
PROMPTS=ROOT/'work/artwork/prompt-authority.json';RECEIPT=ROOT/'log/artwork-provider-attempt-0001.json';SCRIPT=Path.home()/'.hermes/skills/content-creation/tao-anh/scripts/generate_image.py'
def now():return dt.datetime.now(dt.timezone.utc).isoformat().replace('+00:00','Z')
def sha(p):
 h=hashlib.sha256()
 with p.open('rb') as f:
  for b in iter(lambda:f.read(8*1024*1024),b''):h.update(b)
 return h.hexdigest()
def atomic(p,v):
 q=p.with_suffix(p.suffix+'.tmp');q.write_text(json.dumps(v,ensure_ascii=False,indent=2)+'\n',encoding='utf-8');os.replace(q,p)
def guard():
 x=json.loads((ROOT/'.ownership-lock.json').read_text());assert (x['project_id'],x['run_id'],x['owner'],x['status'])==(PROJECT,RUN,OWNER,'main_session_pipeline');assert sha(ROOT/'story/story-canon.txt')==CANON and sha(ROOT/'audio/story-full.wav')==TTS;t=json.loads((ROOT/'log/tts-independent-audit.json').read_text());assert t['status']=='passed' and t['verified'] and t['artwork_gate_open']
def main():
 guard();p=json.loads(PROMPTS.read_text());assert p['status']=='ready_after_tts_gate' and p['source_canon_sha256']==CANON and p['source_tts_sha256']==TTS
 receipt={'schema_version':1,'project_id':PROJECT,'run_id':RUN,'status':'running','verified':False,'source_canon_sha256':CANON,'source_tts_sha256':TTS,'prompt_authority_sha256':sha(PROMPTS),'artifacts':[],'created_at':now()};atomic(RECEIPT,receipt)
 for name in ['intro_poster','left_panel','right_panel']:
  guard();cur=json.loads(PROMPTS.read_text());assert sha(PROMPTS)==receipt['prompt_authority_sha256'];item=cur['artifacts'][name];out=ROOT/item['output'];out.parent.mkdir(parents=True,exist_ok=True);assert not out.exists()
  cmd=[sys.executable,str(SCRIPT),'--prompt',item['prompt'],'--output',str(out),'--n','1','--size','auto','--quality','auto','--background','auto','--detail','high','--format','png','--model','cx/gpt-5.5-image','--timeout','600'];subprocess.run(cmd,check=True);assert out.exists() and out.stat().st_size>0
  sig=out.read_bytes()[:8];assert sig==b'\x89PNG\r\n\x1a\n';receipt['artifacts'].append({'name':name,'output_path':str(out),'bytes':out.stat().st_size,'sha256':sha(out),'provider':'cx/gpt-5.5-image','request_count_for_attempt':1,'typography':'provider_only','status':'generated_waiting_qa'});receipt['updated_at']=now();atomic(RECEIPT,receipt)
 receipt.update({'status':'generated_waiting_qa','completed_at':now()});atomic(RECEIPT,receipt);print(json.dumps({'status':receipt['status'],'artifacts':receipt['artifacts']}))
if __name__=='__main__':main()
