#!/usr/bin/env python3
"""
실행 테스트 자동화 스크립트
- 주요 Python 모듈 import 테스트
- 문법 오류(syntax error) 자동 감지
- --help 또는 기본 실행 테스트
- 결과를 JSON으로 출력
"""

import json
import os
import py_compile
import subprocess
import sys
import tempfile
from pathlib import Path

WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))


def test_syntax(file_path: Path) -> dict:
    """py_compile을 사용한 문법 오류 감지 테스트"""
    result = {
        "file": str(file_path.relative_to(WORKSPACE)),
        "test_type": "syntax",
        "passed": False,
        "error": None,
    }
    try:
        py_compile.compile(str(file_path), doraise=True)
        result["passed"] = True
    except py_compile.PyCompileError as e:
        result["error"] = str(e)
    except FileNotFoundError:
        result["error"] = f"File not found: {file_path}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"
    return result


def test_import(module_path: Path) -> dict:
    """subprocess로 python3 -c 'import ...' 실행하여 모듈 격리 import 테스트"""
    rel = module_path.relative_to(WORKSPACE)
    # 파일 경로를 모듈 표기로 변환 (예: prompts/team_prompts.py -> prompts.team_prompts)
    module_name = ".".join(rel.with_suffix("").parts)

    result = {
        "file": str(rel),
        "test_type": "import",
        "passed": False,
        "error": None,
    }
    try:
        proc = subprocess.run(
            [sys.executable, "-c", f"import sys; sys.path.insert(0, '{WORKSPACE}'); import {module_name}"],
            capture_output=True,
            text=True,
            timeout=30,
        )
        if proc.returncode == 0:
            result["passed"] = True
        else:
            result["error"] = (proc.stderr or proc.stdout).strip()
    except subprocess.TimeoutExpired:
        result["error"] = "Timeout expired during import test"
    except FileNotFoundError:
        result["error"] = f"File not found: {module_path}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"
    return result


def test_help(file_path: Path) -> dict:
    """subprocess로 --help 실행 후 returncode == 0 확인"""
    rel = file_path.relative_to(WORKSPACE)
    result = {
        "file": str(rel),
        "test_type": "help",
        "passed": False,
        "error": None,
    }
    try:
        proc = subprocess.run(
            [sys.executable, str(file_path), "--help"],
            capture_output=True,
            text=True,
            timeout=30,
        )
        if proc.returncode == 0:
            result["passed"] = True
        else:
            result["error"] = (proc.stderr or proc.stdout).strip()
    except subprocess.TimeoutExpired:
        result["error"] = "Timeout expired during --help test"
    except FileNotFoundError:
        result["error"] = f"File not found: {file_path}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"
    return result


def test_basic_run(file_path: Path, args: list = None) -> dict:
    """subprocess로 기본 명령어를 실행하여 정상 동작 확인 (returncode == 0)"""
    rel = file_path.relative_to(WORKSPACE)
    cmd_args = args or []
    result = {
        "file": str(rel),
        "test_type": "basic_run",
        "passed": False,
        "error": None,
    }
    try:
        proc = subprocess.run(
            [sys.executable, str(file_path)] + cmd_args,
            capture_output=True,
            text=True,
            timeout=30,
        )
        if proc.returncode == 0:
            result["passed"] = True
        else:
            result["error"] = (proc.stderr or proc.stdout).strip()
    except subprocess.TimeoutExpired:
        result["error"] = "Timeout expired during basic run test"
    except FileNotFoundError:
        result["error"] = f"File not found: {file_path}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"
    return result


def test_bash_script(script_path: Path) -> dict:
    """bash로 shell script 실행 가능 여부 테스트.

    스크립트가 실행되고 stdout/stderr에 출력을 생성하면 pass.
    health-check.sh 등은 내부 체크 실패 시 non-zero 코드를 반환할 수 있지만,
    스크립트 자체가 실행되면 '실행 테스트'는 통과로 판단.
    """
    rel = script_path.relative_to(WORKSPACE)
    result = {
        "file": str(rel),
        "test_type": "bash_run",
        "passed": False,
        "error": None,
    }
    try:
        proc = subprocess.run(
            ["bash", str(script_path)],
            capture_output=True,
            text=True,
            timeout=30,
        )
        # 스크립트가 실행되어 출력을 생성했으면 pass (내부 체크 실패와 실행 실패를 구분)
        if proc.returncode == 0:
            result["passed"] = True
        elif proc.stdout.strip():
            # 실행은 되었으나 내부 체크 일부 실패 (예: health-check)
            result["passed"] = True
            result["error"] = f"returncode={proc.returncode} (script ran but internal checks may have issues)"
        else:
            result["error"] = (proc.stderr or proc.stdout).strip() or f"returncode={proc.returncode}"
    except subprocess.TimeoutExpired:
        result["error"] = "Timeout expired during bash script test"
    except FileNotFoundError as e:
        result["error"] = f"File not found: {e}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"
    return result


def main():
    results = []

    # 1. dispatch.py -- --help 테스트
    dispatch_py = WORKSPACE / "dispatch.py"
    results.append(test_help(dispatch_py))

    # 2. memory/task-timer.py -- 기본 실행 테스트 (list 명령으로 정상 동작 확인)
    task_timer_py = WORKSPACE / "memory" / "task-timer.py"
    results.append(test_basic_run(task_timer_py, ["list"]))

    # 3. prompts/team_prompts.py -- import 테스트
    team_prompts_py = WORKSPACE / "prompts" / "team_prompts.py"
    results.append(test_import(team_prompts_py))

    # 4. memory/health-check.sh -- bash 실행 테스트
    health_check_sh = WORKSPACE / "memory" / "health-check.sh"
    results.append(test_bash_script(health_check_sh))

    # 결과 집계
    total = len(results)
    passed = sum(1 for r in results if r["passed"])
    failed = total - passed

    summary = {
        "total": total,
        "passed": passed,
        "failed": failed,
        "results": results,
    }

    print(json.dumps(summary, indent=2, ensure_ascii=False))

    sys.exit(0 if failed == 0 else 1)


if __name__ == "__main__":
    main()
