"""auto_approve.py 단위 테스트"""
import importlib.util
import sys
from pathlib import Path
from unittest.mock import MagicMock, patch

PIPELINE_DIR = Path(__file__).parent.parent

# ── 1단계: hook_scorer를 먼저 sys.modules에 등록 ──────────────
spec_hs = importlib.util.spec_from_file_location(
    "hook_scorer", PIPELINE_DIR / "hook_scorer.py"
)
assert spec_hs is not None and spec_hs.loader is not None
hook_scorer = importlib.util.module_from_spec(spec_hs)
sys.modules["hook_scorer"] = hook_scorer
spec_hs.loader.exec_module(hook_scorer)

# ── 2단계: 패키지 mock을 만들어 상대 임포트(.hook_scorer) 우회 ─
_pkg_name = "content_pipeline_pkg"
pkg_mock = MagicMock()
pkg_mock.hook_scorer = hook_scorer
sys.modules[_pkg_name] = pkg_mock

# ── 3단계: auto_approve 로드 — __package__ 를 mock 패키지로 설정
spec_aa = importlib.util.spec_from_file_location(
    f"{_pkg_name}.auto_approve",
    PIPELINE_DIR / "auto_approve.py",
    submodule_search_locations=[],
)
assert spec_aa is not None and spec_aa.loader is not None
auto_approve = importlib.util.module_from_spec(spec_aa)
auto_approve.__package__ = _pkg_name

# 패키지 안에 hook_scorer 노출 (from .hook_scorer import ... 처리)
sys.modules[f"{_pkg_name}.hook_scorer"] = hook_scorer
sys.modules["auto_approve"] = auto_approve
spec_aa.loader.exec_module(auto_approve)

# 편의 별칭
check_copyright_safe = auto_approve.check_copyright_safe
check_blacklist = auto_approve.check_blacklist
check_template_match = auto_approve.check_template_match
check_no_duplicate = auto_approve.check_no_duplicate
approve = auto_approve.approve


# ── 저작권 안전 테스트 ────────────────────────────────────────

class TestCheckCopyrightSafe:
    def test_check_copyright_safe_pass(self):
        """'자체 작성' → True"""
        assert check_copyright_safe("자체 작성") is True

    def test_check_copyright_safe_fail(self):
        """'블로그 복사' → False"""
        assert check_copyright_safe("블로그 복사") is False

    def test_check_copyright_safe_gov(self):
        """'금융감독원 공시' → True"""
        assert check_copyright_safe("금융감독원 공시") is True


# ── 블랙리스트 테스트 ─────────────────────────────────────────

class TestCheckBlacklist:
    def test_check_blacklist_clear(self):
        """정상 텍스트 → 통과(True), 위반 없음"""
        text = "수수료 구조가 바뀐다는 소식입니다."
        passed, violations = check_blacklist(text)
        assert passed is True
        assert violations == []

    def test_check_blacklist_violation(self):
        """블랙리스트 키워드('삼성생명') 포함 → 미통과(False)"""
        text = "삼성생명 상품이 최악이다"
        passed, violations = check_blacklist(text)
        assert passed is False
        assert len(violations) > 0


# ── 템플릿 매칭 테스트 ────────────────────────────────────────

class TestCheckTemplateMatch:
    def test_check_template_match(self):
        """tpl-01 required_keywords('수수료', '변화') 포함 텍스트 → True"""
        text = "수수료 구조의 변화가 업계를 강타하고 있다"
        matched, tpl_id = check_template_match(text)
        assert matched is True
        assert tpl_id is not None

    def test_check_template_no_match(self):
        """템플릿 키워드와 무관한 텍스트 → False"""
        text = "오늘 점심은 김치찌개를 먹었습니다. 맛있었어요."
        matched, tpl_id = check_template_match(text)
        assert matched is False
        assert tpl_id is None


# ── 중복 체크 테스트 ──────────────────────────────────────────

class TestCheckNoDuplicate:
    def test_check_no_duplicate_fresh(self):
        """최근 기록이 없는 새 콘텐츠 → True (중복 아님)"""
        text = "완전히 새로운 고유한 콘텐츠 XYZ_99999"
        # approved / published 디렉토리가 비어있거나 해당 해시가 없으면 True
        with patch.object(auto_approve, "_load_recent_hashes", return_value=set()):
            passed, dup_hash = check_no_duplicate(text)
        assert passed is True
        assert dup_hash is None


# ── 종합 approve 테스트 ──────────────────────────────────────

class TestApprove:
    def _make_templates(self):
        """테스트용 인메모리 템플릿 목록 반환"""
        return [
            {
                "id": "tpl-test",
                "required_keywords": ["수수료", "변화"],
            }
        ]

    def test_approve_all_pass(self):
        """모든 조건 통과 → all_passed=True"""
        # anger(도대체) + fear(안 하면, 큰일) + surprise(진짜)
        text = "수수료 구조의 변화, 도대체 왜 이러는지 모르겠다. 안 하면 진짜 큰일남."
        with (
            patch.object(auto_approve, "_load_templates", return_value=self._make_templates()),
            patch.object(auto_approve, "_load_recent_hashes", return_value=set()),
        ):
            result = approve(text, source="자체 작성")

        assert result.condition_2_copyright_safe is True
        assert result.condition_3_hook_pass is True
        assert result.condition_4_blacklist_clear is True
        assert result.condition_5_no_duplicate is True
        assert result.all_passed is True

    def test_approve_blacklist_fail(self):
        """블랙리스트 저촉 → all_passed=False, condition_4=False"""
        text = "수수료 변화: 삼성생명 관련 안내입니다. 도대체 왜 이러는지, 안 하면 큰일남."
        with (
            patch.object(auto_approve, "_load_templates", return_value=self._make_templates()),
            patch.object(auto_approve, "_load_recent_hashes", return_value=set()),
        ):
            result = approve(text, source="자체 작성")

        assert result.condition_4_blacklist_clear is False
        assert result.all_passed is False
