"""
critical_gap.py - 보고서 CRITICAL 이슈 미수정 검증 verifier

보고서에서 CRITICAL 이슈가 보고되었으나 수정이 확인되지 않으면 FAIL.
"""

import os
import re

DEFAULT_REPORTS_DIR = "/home/jay/workspace/memory/reports"

# CRITICAL 이슈 탐지 키워드 (대소문자 혼용)
CRITICAL_KEYWORDS = ["CRITICAL", "critical", "심각", "블로커"]

# 수정 확인 키워드
RESOLVED_KEYWORDS = ["수정 완료", "해결", "fixed", "resolved"]


def _detect_critical_lines(lines: list[str]) -> list[tuple[int, str]]:
    """
    보고서 줄 목록에서 CRITICAL 키워드가 포함된 줄 탐지.

    Returns:
        [(line_number, line_content), ...] - 1-based line numbers
    """
    found: list[tuple[int, str]] = []
    for i, line in enumerate(lines, start=1):
        for kw in CRITICAL_KEYWORDS:
            if kw in line:
                found.append((i, line.strip()))
                break
    return found


def _detect_resolved_after(lines: list[str], critical_line_num: int) -> bool:
    """
    critical_line_num 이후 줄에서 수정 확인 키워드 탐지.

    Args:
        lines: 전체 줄 목록
        critical_line_num: CRITICAL 이슈가 발견된 줄 번호 (1-based)

    Returns:
        True if resolved keyword found after critical_line_num
    """
    # 보고서 후반부: critical 줄 이후의 줄들 검색
    for line in lines[critical_line_num:]:
        for kw in RESOLVED_KEYWORDS:
            if kw.lower() in line.lower():
                return True
    return False


def verify(task_id: str, report_path: str = "", **kwargs) -> dict:
    """
    보고서에서 CRITICAL 이슈 확인 + 수정 여부 검증.

    보고서 경로: /home/jay/workspace/memory/reports/{task_id}.md
    - CRITICAL 이슈가 있는데 수정 확인이 없으면 FAIL
    - CRITICAL 이슈가 있고 수정 확인도 있으면 PASS
    - CRITICAL 이슈가 없으면 PASS (이슈 없음)
    - 보고서 파일 없으면 SKIP
    - 빈 보고서 → PASS

    Returns:
        {"status": "PASS"|"FAIL"|"WARN"|"SKIP", "details": [...]}
    """
    if not task_id:
        return {"status": "SKIP", "details": ["No task_id provided"]}

    # 보고서 경로 결정
    if report_path:
        path = report_path
    else:
        path = os.path.join(DEFAULT_REPORTS_DIR, f"{task_id}.md")

    # 파일 존재 확인
    if not os.path.exists(path):
        return {
            "status": "SKIP",
            "details": [f"Report not found: {path}"],
        }

    # 파일 읽기
    try:
        with open(path, "r", encoding="utf-8") as f:
            content = f.read()
    except OSError as e:
        return {
            "status": "SKIP",
            "details": [f"Failed to read report: {type(e).__name__}: {e}"],
        }

    lines = content.splitlines()

    # 빈 보고서
    if not lines or not content.strip():
        return {"status": "PASS", "details": ["Report is empty — no CRITICAL issues"]}

    # CRITICAL 이슈 탐지
    critical_lines = _detect_critical_lines(lines)

    if not critical_lines:
        return {
            "status": "PASS",
            "details": [f"No CRITICAL issues found in report: {path}"],
        }

    # CRITICAL 이슈별 수정 확인 여부 체크
    details: list[str] = []
    unresolved: list[str] = []

    for line_num, line_content in critical_lines:
        resolved = _detect_resolved_after(lines, line_num)
        issue_desc = _extract_issue_description(line_content)
        if resolved:
            details.append(f"CRITICAL (line {line_num}) RESOLVED: {issue_desc}")
        else:
            details.append(f"CRITICAL (line {line_num}) UNRESOLVED: {issue_desc}")
            unresolved.append(f"line {line_num}: {issue_desc}")

    if unresolved:
        details.insert(0, f"FAIL — {len(unresolved)} CRITICAL issue(s) not resolved")
        return {"status": "FAIL", "details": details}

    details.insert(0, f"PASS — {len(critical_lines)} CRITICAL issue(s) all resolved")
    return {"status": "PASS", "details": details}


def _extract_issue_description(line: str) -> str:
    """CRITICAL 이슈 줄에서 설명 텍스트 추출 (최대 80자)."""
    # 마크다운 헤더 기호, 번호 목록 기호 등 제거
    cleaned = re.sub(r"^[#\-*\d\.\s]+", "", line).strip()
    if len(cleaned) > 80:
        return cleaned[:80] + "…"
    return cleaned if cleaned else line[:80]
