"""
duplicate_check.py - 보고서 중복 검증 verifier
최근 10개 보고서와 텍스트 유사도 비교 → 80% 이상 일치 시 WARN
"""

import difflib
import os

MEMORY_BASE = "/home/jay/workspace/memory"
REPORTS_DIR = os.path.join(MEMORY_BASE, "reports")


def _read_file(path: str) -> str | None:
    """파일을 읽어 문자열로 반환. 실패 시 None 반환."""
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except OSError:
        return None


def _find_report_path(task_id: str, reports_dir: str) -> str | None:
    """reports_dir에서 task_id에 해당하는 .md 파일 경로 반환. 없으면 None."""
    # 우선 정확한 패턴 탐색
    exact_path = os.path.join(reports_dir, f"{task_id}.md")
    if os.path.isfile(exact_path):
        return exact_path

    # 다른 패턴 탐색 (예: task-4.4.1.md 같은 서브태스크 보고서)
    try:
        entries = os.listdir(reports_dir)
    except OSError:
        return None

    matches = [e for e in entries if e.startswith(task_id) and e.endswith(".md")]
    if matches:
        return os.path.join(reports_dir, matches[0])

    return None


def _get_recent_reports(task_id: str, reports_dir: str, limit: int = 10) -> list[str]:
    """
    reports_dir에서 최근 limit개 .md 파일 경로를 mtime 기준으로 반환.
    현재 task_id의 보고서는 제외.
    """
    try:
        entries = os.listdir(reports_dir)
    except OSError:
        return []

    md_files = []
    for entry in entries:
        if not entry.endswith(".md"):
            continue
        # 현재 task_id 보고서 제외 (task_id로 시작하는 파일 모두 제외)
        if entry.startswith(task_id):
            continue
        full_path = os.path.join(reports_dir, entry)
        if not os.path.isfile(full_path):
            continue
        try:
            mtime = os.path.getmtime(full_path)
        except OSError:
            continue
        md_files.append((mtime, full_path))

    # mtime 내림차순 정렬 → 최신 limit개
    md_files.sort(key=lambda x: x[0], reverse=True)
    return [path for _, path in md_files[:limit]]


def verify(task_id: str, _reports_dir: str = "") -> dict:
    """
    현재 task_id의 보고서를 최근 10개 보고서와 텍스트 유사도 비교.

    Args:
        task_id: 검증할 task ID
        _reports_dir: (테스트용) reports 디렉토리 경로. 기본값은 REPORTS_DIR.

    Returns:
        {"status": "PASS"|"WARN"|"SKIP", "details": [...]}
    """
    reports_dir = _reports_dir if _reports_dir else REPORTS_DIR

    # reports 디렉토리 없으면 SKIP
    if not os.path.isdir(reports_dir):
        return {
            "status": "SKIP",
            "details": [f"reports 디렉토리 없음: {reports_dir}"],
        }

    # 현재 task_id 보고서 찾기
    current_path = _find_report_path(task_id, reports_dir)
    if current_path is None:
        return {
            "status": "SKIP",
            "details": [f"현재 task 보고서 없음: {reports_dir}/{task_id}.md"],
        }

    current_content = _read_file(current_path)
    if not current_content:
        return {
            "status": "SKIP",
            "details": [f"현재 task 보고서를 읽을 수 없거나 비어있음: {current_path}"],
        }

    # 비교 대상 보고서 수집
    recent_reports = _get_recent_reports(task_id, reports_dir, limit=10)
    if not recent_reports:
        return {
            "status": "PASS",
            "details": ["비교 대상 보고서 없음 (중복 검사 생략)"],
        }

    # 유사도 비교
    details: list[str] = []
    warnings: list[str] = []

    for other_path in recent_reports:
        other_content = _read_file(other_path)
        if not other_content:
            continue

        ratio = difflib.SequenceMatcher(None, current_content, other_content).ratio()
        other_name = os.path.basename(other_path)

        if ratio >= 0.80:
            warn_msg = f"WARN: 유사도 {ratio:.1%} — {other_name} 와(과) 높은 유사도 감지 (복사 의심)"
            warnings.append(warn_msg)
            details.append(warn_msg)
        else:
            details.append(f"OK: 유사도 {ratio:.1%} — {other_name}")

    if warnings:
        return {"status": "WARN", "details": details}

    return {"status": "PASS", "details": details if details else ["중복 보고서 없음"]}


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

    tid = sys.argv[1] if len(sys.argv) > 1 else ""
    result = verify(task_id=tid)
    print(json.dumps(result, ensure_ascii=False, indent=2))
