"""
file_touch_ratio_check.py - 보고서 수정 파일 vs 실제 git 변경 파일 비율 검증 verifier

보고서에서 "N개 파일 수정"이라 했는데 실제 git diff에 해당 파일이 없으면 탐지.
"""

import os
import re
import subprocess


def verify(task_id: str, workspace_root: str = "/home/jay/workspace") -> dict:
    """
    보고서에서 수정 파일 목록을 추출하고 실제 git diff와 대조하여
    File-Touch Ratio를 계산합니다.

    Args:
        task_id: 검사 대상 task ID
        workspace_root: 워크스페이스 루트 경로

    Returns:
        {"status": "PASS"|"FAIL"|"WARN"|"SKIP", "details": [...]}
    """
    report_path = os.path.join(workspace_root, "memory", "reports", f"{task_id}.md")

    # 보고서 파일 읽기
    try:
        with open(report_path, "r", encoding="utf-8") as f:
            report_content = f.read()
    except FileNotFoundError:
        return {
            "status": "SKIP",
            "details": [f"보고서 파일 없음: {report_path}"],
        }
    except OSError as e:
        return {
            "status": "SKIP",
            "details": [f"보고서 파일 읽기 실패: {type(e).__name__}: {e}"],
        }

    # 보고서에서 수정 파일 목록 추출
    reported_files = _extract_reported_files(report_content, workspace_root)

    if not reported_files:
        return {
            "status": "SKIP",
            "details": ["보고서에 수정 파일 섹션 없음"],
        }

    # git repo 여부 확인
    try:
        subprocess.run(
            ["git", "-C", workspace_root, "rev-parse", "--git-dir"],
            check=True,
            capture_output=True,
            text=True,
        )
    except subprocess.CalledProcessError:
        return {
            "status": "SKIP",
            "details": [f"git repo 아님: {workspace_root}"],
        }
    except FileNotFoundError:
        return {
            "status": "SKIP",
            "details": ["git 명령어를 찾을 수 없음"],
        }

    # 실제 변경 파일 목록 가져오기 (최근 5커밋)
    try:
        result = subprocess.run(
            ["git", "-C", workspace_root, "diff", "--name-only", "HEAD~5"],
            check=True,
            capture_output=True,
            text=True,
        )
        git_changed_files = set(
            line.strip() for line in result.stdout.splitlines() if line.strip()
        )
    except subprocess.CalledProcessError as e:
        return {
            "status": "SKIP",
            "details": [f"git diff 실행 실패: {e}"],
        }

    # File-Touch Ratio 계산
    reported_set = set(reported_files)
    intersection = reported_set & git_changed_files

    ratio = len(intersection) / len(reported_set) if reported_set else 0.0

    details = [
        f"보고서 파일 수: {len(reported_set)}",
        f"실제 변경 파일 수 (git diff HEAD~5): {len(git_changed_files)}",
        f"교집합: {len(intersection)}",
        f"File-Touch Ratio: {ratio:.2f}",
    ]

    if ratio == 0:
        missing = sorted(reported_set - git_changed_files)
        for f in missing[:10]:
            details.append(f"미변경: {f}")
        return {
            "status": "FAIL",
            "details": details + ["보고서에 명시된 파일 변경 없음"],
        }
    elif ratio < 0.5:
        missing = sorted(reported_set - git_changed_files)
        for f in missing[:10]:
            details.append(f"미변경: {f}")
        return {
            "status": "WARN",
            "details": details + ["보고서 파일의 50% 이상이 실제 변경 안 됨"],
        }
    else:
        return {
            "status": "PASS",
            "details": details,
        }


def _extract_reported_files(report_content: str, workspace_root: str) -> list:
    """
    보고서에서 수정 파일 경로를 추출합니다.

    지원 패턴:
    - 테이블 행: | /home/jay/workspace/... |
    - 목록 항목: - /home/jay/workspace/...
    """
    base = workspace_root.rstrip("/")
    # workspace_root 이후 경로 추출 (상대 경로로 변환)
    # 패턴1: 테이블 행 | /home/jay/workspace/path/to/file |
    # 패턴2: 목록 항목 - /home/jay/workspace/path/to/file
    pattern = re.compile(
        r"(?:^\|[ \t]*|^-[ \t]+)" + re.escape(base) + r"/([^\s|]+)",
        re.MULTILINE,
    )

    matches = pattern.findall(report_content)
    # 중복 제거 및 빈 문자열 필터링
    seen = set()
    result = []
    for m in matches:
        m = m.strip()
        if m and m not in seen:
            seen.add(m)
            result.append(m)
    return result


if __name__ == "__main__":
    import json
    import sys

    if len(sys.argv) < 2:
        print(
            json.dumps(
                {"status": "SKIP", "details": ["Usage: file_touch_ratio_check.py <task_id> [workspace_root]"]},
                ensure_ascii=False,
                indent=2,
            )
        )
        sys.exit(0)

    _task_id = sys.argv[1]
    _workspace_root = sys.argv[2] if len(sys.argv) > 2 else "/home/jay/workspace"
    _result = verify(_task_id, _workspace_root)
    print(json.dumps(_result, ensure_ascii=False, indent=2))
