#!/usr/bin/env python3
"""ensure-bot-memory.sh 테스트

테스트 항목:
1. 스크립트 존재 및 실행 권한
2. 심링크 생성 로직
3. 이미 심링크가 있는 경우 스킵
4. 실행 시간 100ms 이내
"""

import json
import os
import subprocess
import tempfile
import time
from pathlib import Path

import pytest

_WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
SCRIPT_PATH = _WORKSPACE / "scripts/ensure-bot-memory.sh"
SETTINGS_PATH = Path.home() / ".claude" / "settings.json"


class TestScriptExists:
    """스크립트 존재 및 실행 권한 테스트"""

    def test_script_exists(self):
        """스크립트 파일이 존재하는지"""
        assert SCRIPT_PATH.exists(), f"스크립트 없음: {SCRIPT_PATH}"

    def test_script_executable(self):
        """실행 권한이 있는지"""
        assert os.access(SCRIPT_PATH, os.X_OK), f"실행 권한 없음: {SCRIPT_PATH}"


class TestHookRegistered:
    """훅 등록 테스트"""

    def test_hook_in_settings(self):
        """settings.json에 훅이 등록되어 있는지"""
        assert SETTINGS_PATH.exists(), f"settings.json 없음: {SETTINGS_PATH}"

        with open(SETTINGS_PATH, "r", encoding="utf-8") as f:
            settings = json.load(f)

        # UserPromptSubmit 훅 확인
        hooks = settings.get("hooks", {})
        user_prompt_submit = hooks.get("UserPromptSubmit", [])

        # ensure-bot-memory.sh가 포함되어 있는지
        found = False
        for entry in user_prompt_submit:
            for hook in entry.get("hooks", []):
                command = hook.get("command", "")
                if "ensure-bot-memory.sh" in command:
                    found = True
                    break

        assert found, "ensure-bot-memory.sh 훅이 settings.json에 없음"


class TestSymlinkCreation:
    """심링크 생성 테스트"""

    def test_symlink_creation_in_new_dir(self, tmp_path, monkeypatch):
        """새 디렉토리에 심링크 생성"""
        # 가짜 프로젝트 디렉토리 생성
        fake_project = tmp_path / "-home-jay--cokacdir-workspace-test123"
        fake_memory_dir = fake_project / "memory"
        fake_memory_dir.mkdir(parents=True)

        # 원본 MEMORY.md 생성
        source_memory = Path.home() / ".claude/projects/-home-jay--cokacdir-workspace-autoset/memory/MEMORY.md"
        if not source_memory.exists():
            source_memory.parent.mkdir(parents=True, exist_ok=True)
            source_memory.write_text("# Test Memory\n", encoding="utf-8")

        # PWD 환경변수 설정
        test_pwd = "/home/jay/.cokacdir/workspace/test123"
        env = os.environ.copy()
        env["PWD"] = test_pwd

        # 프로젝트 디렉토리를 실제 위치로 이동 (테스트용)
        real_project_dir = Path.home() / ".claude/projects/-home-jay--cokacdir-workspace-test123"
        if real_project_dir.exists():
            import shutil

            shutil.rmtree(real_project_dir)

        # 스크립트 실행
        result = subprocess.run(
            ["bash", str(SCRIPT_PATH)],
            capture_output=True,
            text=True,
            env=env,
            timeout=5,
        )

        # 심링크 생성 확인 (실제 경로에서)
        target_memory = real_project_dir / "memory" / "MEMORY.md"

        # 정리
        if real_project_dir.exists():
            import shutil

            shutil.rmtree(real_project_dir)

        # 에러가 없어야 함
        assert result.returncode == 0, f"스크립트 실패: {result.stderr}"


class TestSkipIfExists:
    """이미 존재하는 경우 스킵 테스트"""

    def test_skip_if_symlink_exists(self):
        """심링크가 이미 있으면 스킵"""
        # autoset 프로젝트에서 실행 (이미 MEMORY.md가 있음)
        env = os.environ.copy()
        env["PWD"] = "/home/jay/.cokacdir/workspace/autoset"

        start_time = time.time()
        result = subprocess.run(
            ["bash", str(SCRIPT_PATH)],
            capture_output=True,
            text=True,
            env=env,
            timeout=5,
        )
        elapsed_ms = (time.time() - start_time) * 1000

        # 빠르게 종료해야 함 (이미 존재하므로)
        assert result.returncode == 0
        # 100ms 이내여야 함
        assert elapsed_ms < 100, f"실행 시간 초과: {elapsed_ms:.1f}ms"


class TestExecutionTime:
    """실행 시간 테스트"""

    def test_execution_time_under_100ms(self):
        """실행 시간이 100ms 이내인지"""
        env = os.environ.copy()
        env["PWD"] = "/home/jay/.cokacdir/workspace/autoset"

        times = []
        for _ in range(5):
            start_time = time.time()
            subprocess.run(
                ["bash", str(SCRIPT_PATH)],
                capture_output=True,
                text=True,
                env=env,
                timeout=5,
            )
            elapsed_ms = (time.time() - start_time) * 1000
            times.append(elapsed_ms)

        avg_time = sum(times) / len(times)
        assert avg_time < 100, f"평균 실행 시간 초과: {avg_time:.1f}ms (측정값: {times})"


class TestWorkspaceCleanup:
    """Workspace 정리 방안 보고"""

    def test_report_temp_files(self):
        """autoset workspace의 임시 파일 보고"""
        autoset_dir = Path("/home/jay/.cokacdir/workspace/autoset")

        if not autoset_dir.exists():
            pytest.skip("autoset 디렉토리 없음")

        # 파일 확장자별 수집
        extensions = {}
        for file in autoset_dir.iterdir():
            if file.is_file():
                ext = file.suffix.lower()
                if ext not in extensions:
                    extensions[ext] = []
                extensions[ext].append(file.name)

        # 보고 (테스트 통과조건 아님)
        report_lines = ["[Workspace 임시 파일 보고]"]
        for ext, files in sorted(extensions.items()):
            report_lines.append(f"  {ext or '(확장자 없음)'}: {len(files)}개")

        # 이 테스트는 항상 통과 (보고용)
        print("\n".join(report_lines))
        assert True


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
