#!/bin/bash
# 아웃룩 재실행이 끝나기를 기다렸다가 → 정렬 검증 → 8샷 재생성 → 갤러리 갱신.
#
# 검증을 중간에 두는 이유: 씬 키가 아직 대본 번호 도메인이면 재생성이 전건
# 거부된다(실측 7/8). 그때 유료 콜을 태우지 않고 멈춘다.
set -u
cd /Users/manta/Documents/Projects/TheRoad-I1/backend
PY=.venv/bin/python

echo "① 아웃룩 재실행 완료 대기"
while pgrep -f "run_outlook_chain.py" > /dev/null; do sleep 20; done
echo "   아웃룩 체인 종료"

echo "② 정렬 검증"
$PY - <<'PYEOF' || { echo "검증 실패 — 재생성을 태우지 않고 멈춘다"; exit 1; }
import json, pathlib, sys
cp = pathlib.Path('/Users/manta/Documents/Projects/TheRoad-I1/projects/e716bafb-24bb-42b7-aea0-fdb383844ee8/checkpoints/episodes/d6a9aa85-b75e-400c-980c-4ee7e876a15b')
segs = json.loads((cp/'scene_save'/'manifest.json').read_text())['data']['segments']
seg_idx = {s['scene_index'] for s in segs}
sd = {s['scene_index']: s for s in json.loads((cp/'scene_director'/'manifest.json').read_text())['data']['scenes']}
d3 = json.loads((cp/'outlook_phase3'/'manifest.json').read_text())['data']
rows = d3.get('scene_assignments') or []
idx = [r.get('scene_index') for r in rows]
outside = sorted(set(idx) - seg_idx)
ol_keys = {k for o in d3.get('outlooks') or [] for k in (o.get('outlook_id'), o.get('short_id')) if k}
tot = res = 0
for r in rows:
    for a in r.get('assignments') or []:
        tot += 1
        if (a.get('outlook_id') or '') in ol_keys: res += 1
print(f"   씬 행 {len(rows)} · 범위 {min(idx)}~{max(idx)} · 세그먼트 밖 {outside or '없음'}")
print(f"   배정 {tot} · outlook_id 해소 {res} ({100*res/max(tot,1):.0f}%)")
by = {r['scene_index']: {a.get('character_id') for a in r.get('assignments') or []} for r in rows}
ok = 0
for si in (11, 15, 88, 7, 8, 9, 12, 17):
    ve = {i for i in sd.get(si, {}).get('present_entity_ids', []) if i.startswith('C')}
    got = by.get(si, set())
    covered = ve <= got
    ok += covered
    print(f"   씬 {si:3}: VE {sorted(ve)} · 아웃룩 {sorted(got)} {'✅' if covered else '❌ 미커버'}")
fail = []
if outside: fail.append(f"씬 키가 세그먼트 밖 {outside}")
if res != tot: fail.append(f"outlook_id 미해소 {tot-res}건")
if ok < 6: fail.append(f"표적 8샷 중 VE 커버 {ok}개뿐")
if fail:
    print("   ✗ " + " / ".join(fail)); sys.exit(1)
print("   ✓ 검증 통과")
PYEOF

echo "③ 8샷 재생성"
$PY regen_drift_fixed_shots.py 2>&1 | tail -25

echo "④ 갤러리 갱신"
$PY build_drift_fix_gallery.py

echo "완료 — http://192.168.35.42:8940/artifact/20260807_scene_director_drift/index.html"
