"""W1-F10 가드: STEP_MANIFEST dict 직참조 제거 검증.

목적: StepRunner와 steps API가 `STEP_MANIFEST` 이름 자체를 import하지 않는지 정적 검사.
함수 API (contains, get_manifest_dict, get_depends_on, get_all_downstream_recursive,
get_step_info 등)는 허용. dict 이름만 금지 — 그래야 런타임 소비자 계약이 단일화된다.
"""
from __future__ import annotations

import ast
from pathlib import Path


def _imported_symbols(py_path: Path, module_prefix: str) -> list[str]:
    """주어진 파일이 module_prefix로 시작하는 모듈에서 import한 심볼명 전부 반환.

    예: imports `from app.core.step_manifest import STEP_MANIFEST, get_depends_on`
    → ["STEP_MANIFEST", "get_depends_on"]
    """
    tree = ast.parse(py_path.read_text(encoding="utf-8"))
    out: list[str] = []
    for node in ast.walk(tree):
        if isinstance(node, ast.ImportFrom) and node.module and node.module.startswith(module_prefix):
            out.extend(alias.name for alias in node.names)
    return out


def test_step_runner_does_not_import_STEP_MANIFEST_dict() -> None:
    path = Path(__file__).resolve().parents[2] / "app" / "core" / "step_runner.py"
    symbols = _imported_symbols(path, "app.core.step_manifest")
    assert "STEP_MANIFEST" not in symbols, (
        f"step_runner.py가 STEP_MANIFEST dict를 직접 import함: {symbols}. "
        f"함수 API(get_manifest_dict, contains 등)만 사용하세요 (W1-F10 계약)."
    )


def test_steps_route_does_not_import_STEP_MANIFEST_dict() -> None:
    path = Path(__file__).resolve().parents[2] / "app" / "api" / "v1" / "steps.py"
    symbols = _imported_symbols(path, "app.core.step_manifest")
    assert "STEP_MANIFEST" not in symbols, (
        f"api/v1/steps.py가 STEP_MANIFEST dict를 직접 import함: {symbols}. "
        f"step_catalog의 함수 API 또는 get_manifest_dict를 사용하세요 (W1-F10 계약)."
    )
