"""tests/lifecycle_guards/test_gemini_gate_validator.py — Group 4 (4건).

task-2472 regression: Gemini gate 검증 강화.

12. test_body_high_zero_thread_medium_blocks_gate
13. test_image_markdown_high_severity_detected
14. test_no_gemini_review_fails_gate
15. test_unresolved_thread_blocks_merge
"""
from __future__ import annotations

import importlib.util
import sys
from pathlib import Path

WORKTREE = Path(__file__).resolve().parents[2]


def _load(mod_name: str, rel: str):
    path = WORKTREE / rel
    spec = importlib.util.spec_from_file_location(mod_name, str(path))
    assert spec is not None and spec.loader is not None, f"spec load 실패: {path}"
    mod = importlib.util.module_from_spec(spec)
    sys.modules[mod_name] = mod
    spec.loader.exec_module(mod)
    return mod


ggv = _load("gemini_gate_validator", "utils/gemini_gate_validator.py")


def _make_pr_data(
    *,
    reviews=None,
    comments=None,
    threads=None,
    issue_comments=None,
    fetch_ok=True,
) -> dict:
    """테스트용 PR 데이터 구성 헬퍼."""
    if reviews is None:
        # 기본: Gemini bot 리뷰 1개
        reviews = [{"user": {"login": "gemini-code-assist[bot]"}, "body": "LGTM no issues found"}]
    if comments is None:
        comments = []
    if threads is None:
        threads = []
    if issue_comments is None:
        issue_comments = []
    return {
        "reviews": reviews,
        "comments": comments,
        "threads": threads,
        "issue_comments": issue_comments,
        "fetch_ok": fetch_ok,
        "errors": [],
    }


# ---------------------------------------------------------------------------
# Test 12: body high=0이지만 unresolved medium thread 1개 → FAIL
# ---------------------------------------------------------------------------

def test_body_high_zero_thread_medium_blocks_gate():
    """review body에 high=0이어도 unresolved medium thread 존재 → FAIL."""
    pr_data = _make_pr_data(
        reviews=[
            {
                "user": {"login": "gemini-code-assist[bot]"},
                "body": "Review complete. No high severity issues in the code body.",
            }
        ],
        threads=[
            {
                "id": "thread-medium-001",
                "isResolved": False,
                "body": "severity: medium — This logic needs improvement.",
            }
        ],
    )

    result = ggv.evaluate_gate(pr_data, block_unresolved_medium=True)

    assert result["verdict"] == "FAIL", f"medium unresolved thread → FAIL 필수: {result}"
    assert result["gemini_review_present"] is True
    assert len(result["unresolved_threads"]) >= 1
    assert any(t["severity"] == "medium" for t in result["unresolved_threads"])


# ---------------------------------------------------------------------------
# Test 13: ![high](url) 텍스트에서 image_high=1 검출
# ---------------------------------------------------------------------------

def test_image_markdown_high_severity_detected():
    """![high](...) 패턴 → detect_image_severity가 high=1 반환."""
    text = "Here is the review: ![high](https://img.shields.io/badge/severity-high-red.svg)"

    result = ggv.detect_image_severity(text)

    assert result["high"] == 1, f"image_high 탐지 실패: {result}"
    assert result["medium"] == 0
    assert result["critical"] == 0
    assert result["low"] == 0

    # evaluate_gate에서도 high image badge → FAIL 확인
    pr_data = _make_pr_data(
        reviews=[
            {
                "user": {"login": "gemini-code-assist[bot]"},
                "body": "![high](https://img.shields.io/badge/severity-high-red.svg) critical path issue found.",
            }
        ],
    )
    gate_result = ggv.evaluate_gate(pr_data)
    assert gate_result["verdict"] == "FAIL", "image badge high → gate FAIL 필수"
    assert gate_result["severity_counts"]["image_high"] >= 1


# ---------------------------------------------------------------------------
# Test 14: latestReviews 중 gemini-code-assist[bot] 없음 → FAIL
# ---------------------------------------------------------------------------

def test_no_gemini_review_fails_gate():
    """Gemini bot 리뷰 없음 → FAIL with 'Gemini review 부재'."""
    pr_data = _make_pr_data(
        reviews=[
            {"user": {"login": "human-reviewer"}, "body": "Looks good to me."},
            {"user": {"login": "other-bot"}, "body": "CI passed."},
        ]
    )

    result = ggv.evaluate_gate(pr_data)

    assert result["verdict"] == "FAIL", "Gemini 리뷰 부재 → FAIL 필수"
    assert result["gemini_review_present"] is False
    assert "Gemini" in result["reason"] or "gemini" in result["reason"].lower()


# ---------------------------------------------------------------------------
# Test 15: unresolved high thread 존재 → FAIL with verdict 명시
# ---------------------------------------------------------------------------

def test_unresolved_thread_blocks_merge():
    """unresolved high thread 존재 → FAIL, verdict=FAIL."""
    pr_data = _make_pr_data(
        reviews=[
            {
                "user": {"login": "gemini-code-assist[bot]"},
                "body": "Review completed.",
            }
        ],
        threads=[
            {
                "id": "thread-high-blocker",
                "isResolved": False,
                "body": "severity: high — Security vulnerability detected in auth module.",
            }
        ],
    )

    result = ggv.evaluate_gate(pr_data)

    assert result["verdict"] == "FAIL", f"unresolved high thread → FAIL 필수: {result}"
    assert len(result["unresolved_threads"]) >= 1
    high_threads = [t for t in result["unresolved_threads"] if t["severity"] == "high"]
    assert len(high_threads) >= 1, "high severity unresolved thread가 목록에 포함되어야 함"
