"""
test_dispatch_phase_warn.py

dispatch._warn_phase_without_task_id() 단위 테스트 (헤임달 작성, task-1894)

테스트 항목:
1. Phase 패턴 + 자동 생성 ID → WARNING 로그 출력됨
2. Phase 패턴 + 수동 지정 ID → 경고 미출력
3. Phase 패턴 없는 일반 task → 경고 미출력
4. 다양한 Phase 패턴 매칭 (Phase 1, phase 2, Phase 1.1, Phase 2.3)
5. Phase가 없는 유사 텍스트 → 미감지 (Phases, phased)
"""

import logging
import sys
from pathlib import Path

import pytest

# ---------------------------------------------------------------------------
# dispatch 모듈 로드
# ---------------------------------------------------------------------------

_WORKSPACE = Path(__file__).parent.parent
sys.path.insert(0, str(_WORKSPACE))

from dispatch import _warn_phase_without_task_id  # type: ignore[import-not-found]

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


class TestWarnPhaseWithoutTaskId:
    """_warn_phase_without_task_id() 동작 검증"""

    # 1. Phase 패턴 + 자동 생성 ID → WARNING 로그 출력됨
    def test_phase_pattern_with_auto_generated_id_logs_warning(self, caplog):
        """Phase 패턴이 감지되고 task_id가 자동 생성 ID와 동일하면 WARNING 로그가 출력된다."""
        auto_id = "auto-20240101-abcd"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 1 작업입니다. 기능 구현을 완료하세요.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" in caplog.text

    # 2. Phase 패턴 + 수동 지정 ID → 경고 미출력
    def test_phase_pattern_with_manual_task_id_no_warning(self, caplog):
        """Phase 패턴이 있어도 task_id가 수동 지정(generated_id와 다름)이면 WARNING이 출력되지 않는다."""
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 2 작업을 시작합니다.",
                task_id="task-1894",
                generated_id="auto-20240101-abcd",
            )
        assert "Phase 작업 감지" not in caplog.text

    # 3. Phase 패턴 없는 일반 task → 경고 미출력
    def test_no_phase_pattern_no_warning(self, caplog):
        """Phase 패턴이 없는 일반 작업 설명에서는 WARNING이 출력되지 않는다."""
        auto_id = "auto-20240101-abcd"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="일반 버그 수정 작업입니다. 로그인 오류를 고쳐주세요.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" not in caplog.text

    # 4a. 다양한 Phase 패턴 매칭 - "Phase 1"
    def test_phase_pattern_uppercase_integer(self, caplog):
        """'Phase 1' 패턴이 감지된다."""
        auto_id = "auto-gen-001"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 1을 완료해야 합니다.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" in caplog.text

    # 4b. 다양한 Phase 패턴 매칭 - "phase 2" (소문자)
    def test_phase_pattern_lowercase_integer(self, caplog):
        """'phase 2' 소문자 패턴이 감지된다."""
        auto_id = "auto-gen-002"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="phase 2 구현을 시작합니다.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" in caplog.text

    # 4c. 다양한 Phase 패턴 매칭 - "Phase 1.1"
    def test_phase_pattern_decimal_1_1(self, caplog):
        """'Phase 1.1' 소수점 패턴이 감지된다."""
        auto_id = "auto-gen-003"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 1.1 디자인 리뷰를 진행합니다.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" in caplog.text

    # 4d. 다양한 Phase 패턴 매칭 - "Phase 2.3"
    def test_phase_pattern_decimal_2_3(self, caplog):
        """'Phase 2.3' 소수점 패턴이 감지된다."""
        auto_id = "auto-gen-004"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="이번 스프린트는 Phase 2.3 완료를 목표로 합니다.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" in caplog.text

    # 5a. 유사 텍스트 미감지 - "Phases"
    def test_phases_plural_not_detected(self, caplog):
        """'Phases'(복수형)는 Phase 패턴으로 감지되지 않는다."""
        auto_id = "auto-gen-005"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phases of the project are defined in the docs.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" not in caplog.text

    # 5b. 유사 텍스트 미감지 - "phased"
    def test_phased_word_not_detected(self, caplog):
        """'phased'(파생어)는 Phase 패턴으로 감지되지 않는다."""
        auto_id = "auto-gen-006"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="This is a phased rollout plan for the new feature.",
                task_id=auto_id,
                generated_id=auto_id,
            )
        assert "Phase 작업 감지" not in caplog.text

    # 추가: 함수는 작업을 차단하지 않음 (반환값 검증)
    def test_function_does_not_block_returns_none(self):
        """함수는 경고만 출력하고 None을 반환한다 (작업 차단 없음)."""
        auto_id = "auto-gen-007"
        result = _warn_phase_without_task_id(
            task_desc="Phase 3 배포 작업을 진행합니다.",
            task_id=auto_id,
            generated_id=auto_id,
        )
        assert result is None

    # 추가: task_id == generated_id 동일 여부 경계값 검증
    def test_task_id_exactly_equal_to_generated_id_triggers_warning(self, caplog):
        """task_id와 generated_id가 정확히 같을 때만 WARNING이 발생한다."""
        same_id = "auto-xyz-9999"
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 4 최종 검수 단계입니다.",
                task_id=same_id,
                generated_id=same_id,
            )
        assert "Phase 작업 감지" in caplog.text

    def test_task_id_differs_from_generated_id_no_warning(self, caplog):
        """task_id와 generated_id가 다를 때는 WARNING이 발생하지 않는다."""
        with caplog.at_level(logging.WARNING, logger="dispatch"):
            _warn_phase_without_task_id(
                task_desc="Phase 4 최종 검수 단계입니다.",
                task_id="task-1000",
                generated_id="auto-xyz-9999",
            )
        assert "Phase 작업 감지" not in caplog.text
