#!/usr/bin/env python3
from pathlib import Path
import base64,json,struct,urllib.request,uuid,wave
P=Path(__file__).resolve().parents[1];assert P.name.startswith('033-')
VOICE='http://192.168.40.32:7861/voice/truong-giang';IMG='http://192.168.40.11:20128/v1/images/generations';ENV=Path('/home/hermes/.hermes/skills/image-generation/gen-img-gpt/references/.env')
intro=(P/'narration/intro.txt').read_text().strip();outro=(P/'narration/outro.txt').read_text().strip();brief=json.loads((P/'logs/poster_brief.json').read_text())
def wavok(f):
 try:
  with wave.open(str(f),'rb') as w:return w.getnframes()>0 and w.getframerate()>0
 except:return False
def pngok(f):
 try:
  d=f.read_bytes();w,h=struct.unpack('>II',d[16:24]);return len(d)>10000 and d[:8]==b'\x89PNG\r\n\x1a\n' and d[-8:-4]==b'IEND' and w>=1024 and h>=576
 except:return False
def tts(text,out):
 if wavok(out):return
 b='----'+uuid.uuid4().hex;parts=[]
 for k,v in [('text',text),('style','tu_nhien'),('speed','1'),('denoise','true')]:parts.append(f'--{b}\r\nContent-Disposition: form-data; name="{k}"\r\n\r\n{v}\r\n'.encode())
 req=urllib.request.Request(VOICE,data=b''.join(parts)+f'--{b}--\r\n'.encode(),headers={'Content-Type':f'multipart/form-data; boundary={b}'},method='POST');tmp=out.with_suffix('.tmp.wav');tmp.write_bytes(urllib.request.urlopen(req,timeout=300).read())
 if not wavok(tmp):raise RuntimeError('invalid WAV')
 tmp.replace(out)
def key():
 for line in ENV.read_text().splitlines():
  if '=' in line and line.split('=',1)[1].strip():return line.split('=',1)[1].strip().strip('"\'')
 raise RuntimeError('missing key')
def image(prompt,out):
 if pngok(out):return
 body={'model':'cx/gpt-5.5-image','prompt':prompt,'size':'1536x1024','response_format':'b64_json'};req=urllib.request.Request(IMG,data=json.dumps(body).encode(),headers={'Authorization':'Bearer '+key(),'Content-Type':'application/json'},method='POST');tmp=out.with_suffix('.tmp.png');tmp.write_bytes(base64.b64decode(json.load(urllib.request.urlopen(req,timeout=1200))['data'][0]['b64_json']))
 if not pngok(tmp):raise RuntimeError('invalid PNG')
 tmp.replace(out)
(P/'audio').mkdir(exist_ok=True);tts(intro,P/'audio/intro.wav');tts(outro,P/'audio/outro.wav')
bi=brief['intro'];prompt=f"Classic stick-figure doodle on a light cream whiteboard-like background, simple black lines with slightly imperfect natural hand-drawn character. High-impact mobile video thumbnail, not a slide. {bi['dominant_focal']} {bi['causal_metaphor']} {bi['typography']} {bi['composition']} Display exactly one Vietnamese headline and no other readable text: TAI CĂNG CỨNG, BỖNG KÊU TÁCH? Preserve the comma and question mark. Bold hierarchy, selective blue orange and red accents, three purposeful layers, no dead space, 16:9."
image(prompt,P/'images/intro_poster.png');image("Classic stick-figure doodle on a light cream whiteboard-like background, simple black hand-drawn lines. Warm celebratory closing composition with large expressive stick figures. Display exactly Bản Năng Cổ Đại and Thanks for watching, no other readable text, no logo or watermark, 16:9.",P/'images/outro_poster.png')
print('ASSET_GATE PASS')
