"""
pyright_check.py - pyright LSP 타입 체크 verifier
Python 파일에 대해 pyright를 실행하여 타입 에러를 검출
"""

import json
import os
import shutil
import subprocess


def _find_project_root(file_paths: list) -> str | None:
    """
    첫 번째 파일의 디렉토리에서 시작하여 부모 디렉토리를 순회하며
    pyrightconfig.json이 존재하는 디렉토리를 반환합니다.
    찾지 못하면 None을 반환합니다.
    """
    if not file_paths:
        return None
    directory = os.path.dirname(os.path.abspath(file_paths[0]))
    while True:
        if os.path.isfile(os.path.join(directory, "pyrightconfig.json")):
            return directory
        parent = os.path.dirname(directory)
        if parent == directory:
            return None
        directory = parent


MINOR_RULES = {
    "reportReturnType",
    "reportArgumentType",
    "reportCallIssue",
    "reportIndexIssue",
    "reportMissingImports",  # import 해소는 프로젝트 설정(pyrightconfig.json) 의존적
}


def verify(file_paths: list, timeout: int = 60) -> dict:
    """
    지정된 Python 파일들에 대해 pyright 타입 체크를 실행합니다.

    Args:
        file_paths: 검사할 파일 경로 목록
        timeout: 최대 실행 시간 (초), 초과 시 SKIP

    Returns:
        {"status": "PASS"|"WARN"|"FAIL"|"SKIP", "details": [...]}
    """
    if not file_paths:
        return {"status": "SKIP", "details": ["No files specified for pyright check"]}

    pyright_bin = shutil.which("pyright")
    if pyright_bin is None:
        return {"status": "SKIP", "details": ["pyright not installed"]}

    py_files = [f for f in file_paths if f.endswith(".py")]
    if not py_files:
        return {"status": "SKIP", "details": ["No Python files found in file_paths"]}

    cmd = [pyright_bin, "--outputjson"] + py_files

    project_root = _find_project_root(py_files)

    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=timeout,
            cwd=project_root,
        )

        try:
            output = json.loads(result.stdout)
        except json.JSONDecodeError:
            return {
                "status": "FAIL",
                "details": [
                    "Failed to parse pyright JSON output",
                    f"stdout: {result.stdout[:300]}",
                ],
            }

        diagnostics = output.get("generalDiagnostics", [])
        errors = [d for d in diagnostics if d.get("severity") == "error"]
        warnings = [d for d in diagnostics if d.get("severity") == "warning"]

        details = [f"{len(errors)} errors, {len(warnings)} warnings found"]

        for diag in diagnostics:
            if diag.get("severity") not in ("error", "warning"):
                continue
            file_path = diag.get("file", "")
            line = diag.get("range", {}).get("start", {}).get("line", 0)
            message = diag.get("message", "")
            rule = diag.get("rule", "")
            rule_suffix = f" ({rule})" if rule else ""
            details.append(f"{file_path}:{line} - {message}{rule_suffix}")

        if len(errors) == 0:
            return {"status": "PASS", "details": details}

        all_minor = all(diag.get("rule") in MINOR_RULES for diag in errors)
        if all_minor:
            return {"status": "WARN", "details": details}

        return {"status": "FAIL", "details": details}

    except subprocess.TimeoutExpired:
        return {
            "status": "SKIP",
            "details": [f"Timeout after {timeout}s — skipping pyright check"],
        }

    except Exception as e:
        return {
            "status": "FAIL",
            "details": [f"Unexpected error running pyright: {type(e).__name__}: {e}"],
        }


if __name__ == "__main__":
    import sys

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