"""
test_dispatch_brainstorming_gate.py

dispatch._check_brainstorming_gate() 단위 테스트 (닌기르수 작성)

테스트 항목:
- UX 키워드 + Lv.3+ + brainstorming 파일 없음 → warning 로그
- skip_brainstorming 플래그로 스킵
- 비UX 키워드는 체크 안 함
- Lv.1(normal)은 체크 안 함
- brainstorming 파일이 있으면 warning 없음
"""

import logging
import os
import sys
import types
from pathlib import Path

import pytest

# ---------------------------------------------------------------------------
# dispatch 모듈 로드 헬퍼
# ---------------------------------------------------------------------------


def _get_dispatch_module() -> types.ModuleType:
    """dispatch 모듈을 sys.modules에서 캐시 없이 로드한다."""
    workspace = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
    if str(workspace) not in sys.path:
        sys.path.insert(0, str(workspace))

    for mod_name in list(sys.modules.keys()):
        if mod_name == "dispatch":
            del sys.modules[mod_name]

    import dispatch as _dispatch  # type: ignore[import-not-found]

    return _dispatch


# ---------------------------------------------------------------------------
# fixture
# ---------------------------------------------------------------------------


@pytest.fixture()
def memory_dir(tmp_path) -> Path:
    """테스트용 memory 디렉토리 (실제 파일 시스템 격리)"""
    d = tmp_path / "memory"
    d.mkdir(parents=True, exist_ok=True)
    return d


@pytest.fixture()
def dispatch_mod(memory_dir):
    """_MEMORY_BASE_PATH가 memory_dir로 교체된 dispatch 모듈"""
    mod = _get_dispatch_module()
    setattr(mod, "_MEMORY_BASE_PATH", memory_dir)  # type: ignore[reportAttributeAccessIssue]
    return mod


# ---------------------------------------------------------------------------
# 테스트 케이스
# ---------------------------------------------------------------------------


class TestCheckBrainstormingGate:
    """_check_brainstorming_gate() 동작 검증"""

    # 시나리오 1: UX 키워드 + Lv.3 + brainstorming 파일 없음 → WARNING
    def test_ux_keyword_critical_no_file_warns(self, dispatch_mod, memory_dir, caplog):
        """UX 키워드 + Lv.3 + brainstorming 파일 없음 → warning 로그 1개 이상 (brainstorming-gate 포함)."""
        # meetings 디렉토리는 있지만 brainstorming 파일 없음
        meetings_dir = memory_dir / "meetings"
        meetings_dir.mkdir(parents=True, exist_ok=True)

        with caplog.at_level(logging.DEBUG, logger="dispatch"):
            dispatch_mod._check_brainstorming_gate("task-9001", "UX 개선 작업", "critical")

        warning_records = [
            r for r in caplog.records
            if r.levelno >= logging.WARNING and "brainstorming-gate" in r.message
        ]
        assert len(warning_records) >= 1, "UX 키워드 + Lv.3 + 파일 없음인데 warning 로그가 없음"

    # 시나리오 2: --skip-brainstorming 사용 시 WARNING 없음
    def test_skip_brainstorming_flag_no_warning(self, dispatch_mod, caplog):
        """skip_brainstorming=True이면 warning 로그 없이 즉시 반환한다."""
        with caplog.at_level(logging.DEBUG, logger="dispatch"):
            dispatch_mod._check_brainstorming_gate(
                "task-9002", "UX 개선 작업", "critical", skip_brainstorming=True
            )

        warning_records = [r for r in caplog.records if r.levelno >= logging.WARNING]
        assert len(warning_records) == 0, "--skip-brainstorming 플래그인데 warning 로그가 발생함"

    # 시나리오 3: 비UX 키워드 + Lv.3 → 체크 안 함
    def test_non_ux_keyword_critical_no_warning(self, dispatch_mod, caplog):
        """비UX 키워드 + Lv.3 → brainstorming 체크를 하지 않아 warning 로그 없음."""
        with caplog.at_level(logging.DEBUG, logger="dispatch"):
            dispatch_mod._check_brainstorming_gate("task-9003", "CI 파이프라인 수정", "critical")

        warning_records = [r for r in caplog.records if r.levelno >= logging.WARNING]
        assert len(warning_records) == 0, "비UX 키워드인데 warning 로그가 발생함"

    # 시나리오 4: Lv.1(normal) → 체크 안 함
    def test_normal_level_no_warning(self, dispatch_mod, caplog):
        """level='normal'(Lv.2)이면 Lv.3 미만이므로 brainstorming 체크를 하지 않는다."""
        with caplog.at_level(logging.DEBUG, logger="dispatch"):
            dispatch_mod._check_brainstorming_gate("task-9004", "UI 버그 수정", "normal")

        warning_records = [r for r in caplog.records if r.levelno >= logging.WARNING]
        assert len(warning_records) == 0, "normal level(Lv.2)인데 warning 로그가 발생함"

    # 시나리오 5: UX 키워드 + Lv.3 + brainstorming 파일 존재 → WARNING 없음
    def test_ux_keyword_critical_file_exists_no_warning(self, dispatch_mod, memory_dir, caplog):
        """brainstorming 파일이 존재하면 warning 없음, info 로그에 '파일 확인됨' 포함."""
        meetings_dir = memory_dir / "meetings"
        meetings_dir.mkdir(parents=True, exist_ok=True)
        brainstorming_file = meetings_dir / "brainstorming-task-9005.md"
        brainstorming_file.write_text("# 브레인스토밍 결과\n- 아이디어 1\n- 아이디어 2\n", encoding="utf-8")

        with caplog.at_level(logging.DEBUG, logger="dispatch"):
            dispatch_mod._check_brainstorming_gate("task-9005", "화면 레이아웃 변경", "critical")

        warning_records = [r for r in caplog.records if r.levelno >= logging.WARNING]
        assert len(warning_records) == 0, "brainstorming 파일이 있는데 warning 로그가 발생함"

        info_records = [r for r in caplog.records if r.levelno == logging.INFO]
        assert any("brainstorming 파일 확인됨" in r.message for r in info_records), \
            "brainstorming 파일 존재 시 info 로그에 '파일 확인됨' 메시지가 없음"
