"""IDS Phase 3 — Mobile Prototype regression tests.

10 tests covering frame dimensions, Dynamic Island, hole-punch, status bar,
all 7 Korean scenarios, SKILL.md frontmatter, external API blocklist,
and py_compile of both scripts.
"""

from __future__ import annotations

import re
import subprocess
import sys
from pathlib import Path

import pytest

PROJECT_ROOT = "/home/jay/workspace"
SKILL_DIR = Path(PROJECT_ROOT) / "skills" / "mobile-prototype-ko"
FRAMES_DIR = SKILL_DIR / "frames"
SCENARIOS_DIR = SKILL_DIR / "scenarios"
SCRIPTS_DIR = SKILL_DIR / "scripts"

IPHONE_LIGHT = FRAMES_DIR / "iphone15pro_light.html"
IPHONE_DARK = FRAMES_DIR / "iphone15pro_dark.html"
PIXEL_LIGHT = FRAMES_DIR / "pixel9pro_light.html"
PIXEL_DARK = FRAMES_DIR / "pixel9pro_dark.html"

ALL_SCENARIOS = [
    "signup_step1",
    "signup_step2",
    "signup_step3",
    "dashboard",
    "insurance_compare",
    "cardnews_publish",
    "ai_analysis",
]

KOREAN_RE = re.compile(r"[가-힣]")
BLOCKED_URLS = (
    "openai.com",
    "api.anthropic.com",
    "generativelanguage.googleapis.com",
)


def test_iphone15pro_frame_dimensions() -> None:
    """iPhone 15 Pro light frame must declare 393x852 viewport."""
    assert IPHONE_LIGHT.is_file(), f"missing: {IPHONE_LIGHT}"
    css = IPHONE_LIGHT.read_text(encoding="utf-8")
    assert "width: 393px" in css
    assert "height: 852px" in css


def test_pixel9pro_frame_dimensions() -> None:
    """Pixel 9 Pro light frame must declare 412x915 viewport."""
    assert PIXEL_LIGHT.is_file(), f"missing: {PIXEL_LIGHT}"
    css = PIXEL_LIGHT.read_text(encoding="utf-8")
    assert "width: 412px" in css
    assert "height: 915px" in css


def test_dynamic_island_present() -> None:
    """Both iPhone frames have .dynamic-island with 120px width and border-radius."""
    for path in (IPHONE_LIGHT, IPHONE_DARK):
        text = path.read_text(encoding="utf-8")
        assert ".dynamic-island" in text, f"no .dynamic-island in {path}"
        assert "width: 120px" in text, f"no width: 120px in {path}"
        assert "border-radius:" in text, f"no border-radius in {path}"


def test_pixel_hole_punch_present() -> None:
    """Both Pixel frames have .hole-punch (or .camera-cutout) class."""
    for path in (PIXEL_LIGHT, PIXEL_DARK):
        text = path.read_text(encoding="utf-8")
        assert (
            ".hole-punch" in text or ".camera-cutout" in text
        ), f"no hole-punch class in {path}"


def test_status_bar_renders() -> None:
    """All 4 frames contain .status-bar class and the time text 9:41."""
    for path in (IPHONE_LIGHT, IPHONE_DARK, PIXEL_LIGHT, PIXEL_DARK):
        text = path.read_text(encoding="utf-8")
        assert ".status-bar" in text, f"no .status-bar in {path}"
        assert "9:41" in text, f"no 9:41 time in {path}"


def test_dark_light_modes_exist() -> None:
    """All 4 frame files (iPhone light/dark, Pixel light/dark) exist."""
    for path in (IPHONE_LIGHT, IPHONE_DARK, PIXEL_LIGHT, PIXEL_DARK):
        assert path.is_file(), f"frame not found: {path}"


def test_all_5_scenarios_exist_with_korean() -> None:
    """All 7 scenario HTML files exist and contain Korean characters."""
    for scenario in ALL_SCENARIOS:
        path = SCENARIOS_DIR / f"{scenario}.html"
        assert path.is_file(), f"missing scenario: {path}"
        text = path.read_text(encoding="utf-8")
        assert KOREAN_RE.search(text), f"no Korean in {path}"


def test_skill_md_metadata() -> None:
    """SKILL.md begins with YAML frontmatter containing name and description."""
    skill_md = SKILL_DIR / "SKILL.md"
    assert skill_md.is_file(), f"missing: {skill_md}"
    text = skill_md.read_text(encoding="utf-8")
    head = text.lstrip()
    assert head.startswith("---"), "SKILL.md must start with --- frontmatter"
    # Cap inspection to first ~600 chars to verify name + description
    front = head[:800]
    assert "name: mobile-prototype-ko" in front
    assert "description:" in front


def test_no_external_api_direct_calls() -> None:
    """render_prototype.py and validate_korean_ocr.py must not contain blocked URLs."""
    for script_name in ("render_prototype.py", "validate_korean_ocr.py"):
        path = SCRIPTS_DIR / script_name
        assert path.is_file(), f"missing script: {path}"
        text = path.read_text(encoding="utf-8")
        for blocked in BLOCKED_URLS:
            assert blocked not in text, f"{path} contains blocked URL: {blocked}"


def test_render_script_imports_ok() -> None:
    """Both Python scripts must compile via py_compile (no syntax errors)."""
    for script_name in ("render_prototype.py", "validate_korean_ocr.py"):
        path = SCRIPTS_DIR / script_name
        result = subprocess.run(
            [sys.executable, "-m", "py_compile", str(path)],
            capture_output=True,
            text=True,
            check=False,
        )
        assert result.returncode == 0, (
            f"py_compile failed for {path}:\n{result.stderr}"
        )


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
