"""tests/lifecycle_guards/test_gemini_image_severity.py — task-2471 회귀 테스트.

토르가 commit 0750481e 에서 ``scripts/gemini_severity_parser.py`` 에 추가한
이미지 alt-text severity 패턴 (``![High](url)`` / ``![Critical](...)`` /
``![Blocking](...)``) 을 영구 차단한다.

- ``_HIGH_IMAGE_LABEL`` 정규식 노출
- ``count_severities`` 가 image hits 를 high 카운트에 반영
- 대소문자 무관 (``re.IGNORECASE``)
- code block 안의 ``![High]`` 는 strip (false positive 방지)
- ``match_high_severity`` 도 image label 인식

헤임달(개발2팀 테스터) 작성.
"""
from __future__ import annotations

import importlib.util
import re
import sys
from pathlib import Path

import pytest

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


@pytest.fixture(scope="module")
def gsp():
    """``scripts/gemini_severity_parser.py`` 절대 경로 로드."""
    file_path = WORKSPACE / "scripts" / "gemini_severity_parser.py"
    assert file_path.exists(), f"missing: {file_path}"
    spec = importlib.util.spec_from_file_location(
        "gemini_severity_parser_test_alias", str(file_path)
    )
    assert spec is not None and spec.loader is not None
    mod = importlib.util.module_from_spec(spec)
    sys.modules[spec.name] = mod
    spec.loader.exec_module(mod)
    return mod


# ---------------------------------------------------------------------------
# _HIGH_IMAGE_LABEL 정규식 노출 검증
# ---------------------------------------------------------------------------


def test_high_image_label_pattern_exposed(gsp):
    assert hasattr(gsp, "_HIGH_IMAGE_LABEL"), "_HIGH_IMAGE_LABEL 미노출"
    assert isinstance(gsp._HIGH_IMAGE_LABEL, re.Pattern)


# ---------------------------------------------------------------------------
# count_severities — image label
# ---------------------------------------------------------------------------


def test_count_severities_image_high(gsp):
    """``![High](url)`` 패턴 1건 -> high >= 1."""
    out = gsp.count_severities("Issue: ![High](https://x.com/badge.svg)")
    assert out["high"] >= 1


def test_count_severities_image_critical(gsp):
    out = gsp.count_severities("Found: ![Critical](https://x.com/c.png)")
    assert out["high"] >= 1


def test_count_severities_image_blocking(gsp):
    out = gsp.count_severities("Status: ![Blocking](https://x.com/b.png)")
    assert out["high"] >= 1


def test_count_severities_image_case_insensitive(gsp):
    """소문자 ``![high]`` 도 인식."""
    out = gsp.count_severities("![high](url) ![CRITICAL](url) ![blocking](url)")
    assert out["high"] >= 3


def test_count_severities_normal_text_zero(gsp):
    """이미지 패턴 없는 일반 텍스트는 high=0."""
    out = gsp.count_severities("Normal text with no severity markers.")
    assert out["high"] == 0


def test_count_severities_image_in_code_block_excluded(gsp):
    """code block 안의 ``![High]`` 는 strip 되어 high=0."""
    body = (
        "Here is example code:\n"
        "```\n"
        "![High](url)\n"
        "```\n"
        "End of example."
    )
    out = gsp.count_severities(body)
    assert out["high"] == 0, (
        f"code block 내부 패턴이 false-positive 로 카운트됨: hits={out['high_hits']}"
    )


def test_count_severities_image_in_inline_code_excluded(gsp):
    """inline code (``...``) 안의 ``![High]`` 도 strip."""
    body = "Use the marker `![High](url)` in your text. Nothing severe."
    out = gsp.count_severities(body)
    assert out["high"] == 0


# ---------------------------------------------------------------------------
# high_hits 에 image:... 항목 포함
# ---------------------------------------------------------------------------


def test_high_hits_contains_image_prefix(gsp):
    """``high_hits`` 리스트에 ``image:...`` 형식 항목 포함."""
    out = gsp.count_severities("![High](https://x/a.png)")
    assert any(h.startswith("image:") for h in out["high_hits"]), (
        f"image: prefix hit 없음: {out['high_hits']}"
    )


def test_match_high_severity_includes_image_hit(gsp):
    """기존 호환 함수 ``match_high_severity`` 도 image 인식."""
    hits = gsp.match_high_severity("![Critical](url)")
    # match_high_severity 는 패턴 type별 1건 반환
    assert any("image" in h for h in hits), f"match_high_severity image 미포함: {hits}"


# ---------------------------------------------------------------------------
# 다중 image label 카운트
# ---------------------------------------------------------------------------


def test_multiple_image_labels_counted_separately(gsp):
    body = (
        "Three image badges:\n"
        "![High](u1) ![Critical](u2) ![Blocking](u3)\n"
    )
    out = gsp.count_severities(body)
    # 최소 3건 이상 (각 image label 1건씩)
    image_hits = [h for h in out["high_hits"] if h.startswith("image:")]
    assert len(image_hits) >= 3, f"image hits 부족: {image_hits}"


def test_has_high_severity_returns_true_for_image(gsp):
    """``has_high_severity`` 헬퍼도 image 패턴에서 True."""
    assert gsp.has_high_severity("![High](u)") is True
    assert gsp.has_high_severity("clean body") is False
