#!/usr/bin/env python3
from pathlib import Path
import datetime as dt, hashlib, json, os, stat, subprocess

ROOT = Path('/data/video-pipeline/HaTramAudio/project/021-Ngay-Toi-Bi-Gach-Ten-Khoi-Gia-Pha')
RUN = 'run-20260721T131911Z-ac5d64d1'
CANON = 'bb80e97d9adcb0427ea3828449858445323db228cca38f37cdf0446fffefdd6f'
SCRIPT = Path.home() / '.hermes/skills/content-creation/tao-anh/scripts/generate_image.py'
OUT = ROOT / 'image/provider/left-panel-provider.png'
RECEIPT = ROOT / 'log/artwork-left-v3.json'


def now():
    return dt.datetime.now(dt.timezone.utc).isoformat().replace('+00:00', 'Z')


def sha(path):
    h = hashlib.sha256()
    with open(path, 'rb') as f:
        while block := f.read(8 * 1024 * 1024):
            h.update(block)
    return h.hexdigest()


def atomic(path, value):
    temp = path.with_suffix(path.suffix + '.tmp')
    temp.write_text(json.dumps(value, ensure_ascii=False, indent=2) + '\n')
    temp.replace(path)


def load_env():
    env = os.environ.copy()
    source = Path.home() / '.hermes/.env'
    if not all(env.get(k) for k in ('TAO_ANH_API_KEY', 'TAO_ANH_API_URL')):
        assert source.exists() and stat.S_IMODE(source.stat().st_mode) == 0o600
        for line in source.read_text().splitlines():
            if '=' in line and not line.lstrip().startswith('#'):
                key, value = line.split('=', 1)
                env.setdefault(key.strip(), value.strip().strip('"').strip("'"))
    assert all(env.get(k) for k in ('TAO_ANH_API_KEY', 'TAO_ANH_API_URL'))
    return env


def main():
    revision = json.loads((ROOT / 'work/artwork/left-revision-v3.json').read_text())
    lock = json.loads((ROOT / '.ownership-lock.json').read_text())
    assert lock['run_id'] == RUN and lock['owner'] == 'zoro'
    assert lock['status'] == 'main_session_pipeline'
    assert sha(ROOT / 'story/story-canon.txt') == CANON
    assert sha(ROOT / 'image/provider/intro-poster-provider.png') == revision['reuse_locked']['intro_sha256']
    assert sha(ROOT / 'image/provider/right-panel-provider.png') == revision['reuse_locked']['right_sha256']
    assert sha(Path(revision['rejected_v1']['path'])) == revision['rejected_v1']['sha256']
    assert sha(Path(revision['rejected_v2']['path'])) == revision['rejected_v2']['sha256']
    intent = {
        'schema_version': 1, 'project_id': ROOT.name, 'run_id': RUN,
        'revision': 3, 'status': 'creating', 'verified': False,
        'prompt_sha256': revision['prompt_sha256'],
        'source_canon_sha256': CANON, 'output_path': str(OUT),
        'credential': '[REDACTED]', 'created_at': now(),
    }
    atomic(RECEIPT, intent)
    completed = subprocess.run(
        ['python3', str(SCRIPT), '--prompt', revision['prompt'], '--output', str(OUT), '--timeout', '600'],
        env=load_env(), capture_output=True, text=True,
    )
    if completed.returncode != 0:
        intent.update({'status': 'failed', 'failure': 'provider command failed; stderr redacted', 'failed_at': now()})
        atomic(RECEIPT, intent)
        raise RuntimeError('provider failed')
    assert OUT.exists() and OUT.read_bytes()[:8] == b'\x89PNG\r\n\x1a\n'
    intent.update({
        'status': 'completed', 'technical_verified': True,
        'verified': False, 'awaiting_visual_qa': True,
        'artifact_sha256': sha(OUT), 'size_bytes': OUT.stat().st_size,
        'completed_at': now(),
    })
    atomic(RECEIPT, intent)
    print(json.dumps({'status': 'left_v3_generated', 'path': str(OUT), 'sha256': sha(OUT), 'bytes': OUT.stat().st_size}, ensure_ascii=False))


if __name__ == '__main__':
    main()