import json
import re
import sys
from pathlib import Path

sys.stdout.reconfigure(encoding='utf-8')

registry_path = Path(".agents/teamwork/spec_miner_m2_3/ep01_muse_prompts_188_shots.json")
with open(registry_path, "r", encoding="utf-8") as f:
    prompts = json.load(f)

print(f"Total entries loaded: {len(prompts)}")

# Test 1: Count
assert len(prompts) == 188, f"Expected 188 shots, got {len(prompts)}"
print("✓ Test 1: Exactly 188 shots")

# Test 2: Shot ID format
pattern = re.compile(r"^ep01_scene\d{2}_shot\d{2}$", re.IGNORECASE)
invalid_ids = [k for k in prompts if not pattern.match(k)]
assert len(invalid_ids) == 0, f"Invalid IDs: {invalid_ids}"
print("✓ Test 2: All shot IDs conform to ep01_sceneXX_shotYY")

# Test 3: Audio Guard
unguarded_audio = []
for k, v in prompts.items():
    text = json.dumps(v, ensure_ascii=False).lower()
    if "tuyệt đối không sinh nhạc nền" not in text and "no music" not in text:
        unguarded_audio.append(k)
assert len(unguarded_audio) == 0, f"Missing audio guard: {unguarded_audio}"
print("✓ Test 3: 100% of shots contain mandatory Audio Guard clause")

# Test 4: Length >= 50
short_prompts = []
for k, v in prompts.items():
    m_text = v.get("motion_prompt", "")
    if len(m_text.strip()) < 50:
        short_prompts.append((k, len(m_text)))
assert len(short_prompts) == 0, f"Prompts too short: {short_prompts}"
print("✓ Test 4: 100% of prompts >= 50 characters (average length:", sum(len(v["motion_prompt"]) for v in prompts.values()) // len(prompts), "chars)")

# Test 5: Lip-sync guard in offscreen / distant / VO dialogue
lip_sync_failed = []
for shot_id, shot_info in prompts.items():
    audio_text = shot_info.get("audio_prompt", "").lower()
    motion_text = shot_info.get("motion_prompt", "").lower()
    if "từ xa" in audio_text or "ngoài khung" in audio_text or "v.o." in audio_text:
        has_closed_lips = any(w in motion_text for w in ["khép chặt", "khép môi", "lips closed", "không mấp máy"])
        if not has_closed_lips:
            lip_sync_failed.append(shot_id)
assert len(lip_sync_failed) == 0, f"Failed lip-sync offscreen guard: {lip_sync_failed}"
print("✓ Test 5: 100% of offscreen/distant/VO dialogue shots enforce closed lips")

# Test 6: Scene 08 Shot 02 & Shot 08
c08_s02 = prompts.get("ep01_scene08_shot02", {})
m08_02 = c08_s02.get("motion_prompt", "").lower()
assert any(w in m08_02 for w in ["khép môi", "khép chặt", "lips closed", "không mấp máy"]), "Scene 08 Shot 02 missing lip guard"

c08_s08 = prompts.get("ep01_scene08_shot08", {})
m08_08 = c08_s08.get("motion_prompt", "").lower()
assert any(w in m08_08 for w in ["khép môi", "khép chặt", "lips closed", "không mấp máy"]), "Scene 08 Shot 08 missing lip guard"
print("✓ Test 6: Scene 08 Shot 02 and Shot 08 strictly enforce Kim Trọng lip guard")

# Test 7: Directional motion guard (anti reverse physics)
reverse_guard_failed = []
for shot_id, shot_info in prompts.items():
    m = shot_info.get("motion_prompt", "")
    if not bool(re.search(r"(bay về phía trước|tuyệt đối không|chuyển động tự nhiên|thuận chiều)", m, re.IGNORECASE)):
        reverse_guard_failed.append(shot_id)
assert len(reverse_guard_failed) == 0, f"Failed reverse motion guard: {reverse_guard_failed}"
print("✓ Test 7: 100% of shots contain reverse physics motion guard")

# Test 8: Anti-Male-Tears
# Verify male crying forbidden
male_crying_keywords = ["khóc nức nở", "lệ rơi", "nước mắt lưng tròng", "khóc thương", "rơi lệ", "gào khóc", "nước mắt tuôn trào"]
male_tears_violations = []
for shot_id, shot_info in prompts.items():
    m = shot_info.get("motion_prompt", "")
    # If male character is the subject and weeping is described for male
    for male in ["Kim Trọng", "Vương Quan", "Vương Ông", "Từ Hải"]:
        if male in m:
            # check if male is doing the crying
            for kw in male_crying_keywords:
                pattern_weep = rf"{male}[^.;]*{kw}"
                if re.search(pattern_weep, m, re.IGNORECASE):
                    male_tears_violations.append((shot_id, male, kw))
assert len(male_tears_violations) == 0, f"Anti-Male-Tears violations: {male_tears_violations}"
print("✓ Test 8: 100% compliance with Anti-Male-Tears directive (0% male crying)")

# Test 9: Target video file versioning
versioning_failed = []
for shot_id, shot_info in prompts.items():
    tgt = shot_info.get("target_video_file", "")
    if not (tgt.endswith("_10s_v1.mp4") and tgt.startswith(shot_id)):
        versioning_failed.append((shot_id, tgt))
assert len(versioning_failed) == 0, f"Versioning failed: {versioning_failed}"
print("✓ Test 9: 100% of shots reference _10s_v1.mp4 target file naming")

print("\nALL 9 RIGOROUS VERIFICATION CHECKS PASSED PERFECTLY!")
