"""
회귀 테스트 (test_regression.py)

이전 버그가 재발하지 않도록 핵심 회귀 케이스 등록:
1. TestCLIMain 재귀 이슈 방어 (monkeypatch 안전성)
2. dev3 GLM 프롬프트에 팀원 이름 대신 팀 ID 포함 확인
3. task-timer.py --help 미지원 확인 (run_tests.py 호환성)
4. generate_task_id() 기존 ID와 충돌 없음 확인
"""

import importlib
import importlib.util
import json
import os
import sys
from pathlib import Path

import pytest

# workspace를 sys.path에 추가
_WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
if str(_WORKSPACE) not in sys.path:
    sys.path.insert(0, str(_WORKSPACE))

# task-timer 모듈 로드
_TIMER_MODULE_PATH = _WORKSPACE / "memory" / "task-timer.py"


def _load_task_timer_module():
    spec = importlib.util.spec_from_file_location("task_timer", _TIMER_MODULE_PATH)
    assert spec is not None and spec.loader is not None
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


_task_timer_mod = _load_task_timer_module()
TaskTimer = _task_timer_mod.TaskTimer
_main_func = _task_timer_mod.main
_original_init = TaskTimer.__init__


# dispatch 모듈 로드 (WORKSPACE를 격리)
def _load_dispatch_with_workspace(tmp_path):
    import prompts.team_prompts

    for mod_name in list(sys.modules.keys()):
        if mod_name == "dispatch":
            del sys.modules[mod_name]
    import dispatch as _dispatch

    _dispatch.WORKSPACE = tmp_path
    return _dispatch


import prompts.team_prompts as tp


class TestRegressionCLIRecursion:
    """회귀 #1: TestCLIMain monkeypatch 재귀 이슈 방어"""

    def test_patched_init_does_not_recurse(self, tmp_path):
        """monkeypatch된 __init__이 원본을 호출하며 무한 재귀가 발생하지 않음"""
        (tmp_path / "memory").mkdir(parents=True, exist_ok=True)

        def patched_init(self, workspace_path=None):
            _original_init(self, str(tmp_path))

        # 직접 인스턴스 생성하여 재귀가 발생하지 않는지 확인
        TaskTimer.__init__ = patched_init
        try:
            timer = TaskTimer()
            assert timer.timer_file == tmp_path / "memory" / "task-timers.json"
        finally:
            TaskTimer.__init__ = _original_init

    def test_original_init_preserved(self):
        """원본 __init__이 보존되어 있음"""
        assert _original_init is not None
        assert callable(_original_init)


class TestRegressionDev8GLMPrompt:
    """회귀 #2: dev8 GLM 프롬프트에 팀 ID 포함, 개별 팀원 이름이 직접 표시되지 않음"""

    @pytest.fixture()
    def dev8_prompt(self, tmp_path):
        """dev8-team 프롬프트를 생성 (파일 쓰기 격리)"""
        task_dir = tmp_path / "memory" / "tasks"
        task_dir.mkdir(parents=True, exist_ok=True)

        original_write_text = Path.write_text
        original_mkdir = Path.mkdir

        def patched_write_text(self_path, content, encoding=None):
            path_str = str(self_path)
            if f"{_WORKSPACE}/memory/tasks/" in path_str:
                filename = self_path.name
                redirected = task_dir / filename
                return original_write_text(redirected, content, encoding=encoding)
            return original_write_text(self_path, content, encoding=encoding)

        def patched_mkdir(self_path, parents=False, exist_ok=False):
            path_str = str(self_path)
            if f"{_WORKSPACE}/memory/tasks" in path_str:
                return
            return original_mkdir(self_path, parents=parents, exist_ok=exist_ok)

        import unittest.mock

        with (
            unittest.mock.patch.object(Path, "write_text", patched_write_text),
            unittest.mock.patch.object(Path, "mkdir", patched_mkdir),
        ):
            prompt = tp.build_prompt("dev8-team", "task-reg-1", "GLM 회귀 테스트")

        return prompt

    def test_dev8_prompt_contains_team_id(self, dev8_prompt):
        """dev8 프롬프트에 'dev8-team' 포함"""
        assert "dev8-team" in dev8_prompt

    def test_dev8_prompt_type_is_mcp(self):
        """dev8-team의 type이 'mcp'"""
        assert tp.TEAM_INFO["dev8-team"]["type"] == "mcp"


class TestRegressionTaskTimerHelp:
    """회귀 #3: task-timer.py --help 미지원 (argparse 미사용)"""

    def test_no_args_exits_with_usage(self, monkeypatch, capsys):
        """인자 없이 실행하면 Usage 출력 후 exit(1)"""
        monkeypatch.setattr(sys, "argv", ["task-timer.py"])
        with pytest.raises(SystemExit) as exc_info:
            _main_func()
        assert exc_info.value.code == 1
        captured = capsys.readouterr()
        assert "Usage" in captured.out

    def test_list_command_works_without_args(self, tmp_path, monkeypatch, capsys):
        """list 명령어는 인자 없이도 정상 동작"""

        def patched_init(self, workspace_path=None):
            _original_init(self, str(tmp_path))

        monkeypatch.setattr(TaskTimer, "__init__", patched_init)
        monkeypatch.setattr(sys, "argv", ["task-timer.py", "list"])
        _main_func()
        captured = capsys.readouterr()
        output = json.loads(captured.out)
        assert "total" in output


class TestRegressionGenerateTaskIdCollision:
    """회귀 #4: generate_task_id() 기존 ID와 충돌 없음"""

    @pytest.fixture()
    def dispatch_mod(self, tmp_path):
        (tmp_path / "memory").mkdir(parents=True, exist_ok=True)
        (tmp_path / "memory" / "tasks").mkdir(parents=True, exist_ok=True)
        return _load_dispatch_with_workspace(tmp_path)

    def test_no_collision_with_existing_ids(self, dispatch_mod, tmp_path):
        """기존 ID가 있을 때 새 ID는 다른 값"""
        timer_file = tmp_path / "memory" / "task-timers.json"
        existing = {
            "tasks": {
                "task-1.1": {"status": "completed"},
                "task-2.1": {"status": "running"},
            }
        }
        timer_file.write_text(json.dumps(existing), encoding="utf-8")
        new_id = dispatch_mod.generate_task_id()
        assert new_id not in existing["tasks"]

    def test_sequential_ids_never_collide(self, dispatch_mod, tmp_path):
        """연속 생성된 ID들이 서로 충돌하지 않음"""
        ids = set()
        for _ in range(10):
            task_id = dispatch_mod.generate_task_id()
            assert task_id not in ids, f"중복 ID 발생: {task_id}"
            ids.add(task_id)

    def test_new_id_is_higher_than_existing(self, dispatch_mod, tmp_path):
        """새 ID의 숫자가 기존 최대 ID보다 큼"""
        timer_file = tmp_path / "memory" / "task-timers.json"
        existing = {
            "tasks": {
                "task-5.1": {"status": "completed"},
                "task-10.1": {"status": "running"},
            }
        }
        timer_file.write_text(json.dumps(existing), encoding="utf-8")
        new_id = dispatch_mod.generate_task_id()
        # task-10.1이 최대이므로 다음은 task-11이어야 함
        assert new_id == "task-11"
