"""SnapshotService 단위 테스트 — Phase 2.3."""
from __future__ import annotations

from pathlib import Path
from unittest.mock import MagicMock

import pytest

from app.core.errors import AppError
from app.services.snapshot_service import SnapshotService


@pytest.fixture
def project_episode(tmp_path: Path, monkeypatch):
    monkeypatch.setattr("app.core.config.settings.projects_dir", str(tmp_path))
    return "p1", "e1"


def test_list_versions_no_dir_empty(project_episode):
    pid, eid = project_episode
    db = MagicMock()
    result = SnapshotService(db, pid, eid).list_versions()
    assert result == {"snapshots": []}


def test_list_versions_ignores_prerestore(project_episode, tmp_path):
    pid, eid = project_episode
    step_dir = tmp_path / pid / "checkpoints" / "episodes" / eid / "text_cleanup"
    step_dir.mkdir(parents=True)
    (step_dir / "manifest_20260401_120000.json").write_text("{}", encoding="utf-8")
    (step_dir / "manifest_20260401_130000_prerestore.json").write_text("{}", encoding="utf-8")

    db = MagicMock()
    result = SnapshotService(db, pid, eid).list_versions()
    versions = [s["version"] for s in result["snapshots"]]
    assert "20260401_120000" in versions
    assert "20260401_130000" not in versions


def test_save_snapshot_no_checkpoint_dir_raises(project_episode):
    pid, eid = project_episode
    db = MagicMock()
    with pytest.raises(AppError) as exc_info:
        SnapshotService(db, pid, eid).save_snapshot()
    assert exc_info.value.code == "snapshot.no_checkpoints"


def test_restore_no_checkpoint_dir_raises(project_episode):
    pid, eid = project_episode
    db = MagicMock()
    with pytest.raises(AppError) as exc_info:
        SnapshotService(db, pid, eid).restore(version="20260101_000000")
    assert exc_info.value.code == "snapshot.not_found"


def test_restore_missing_version_raises(project_episode, tmp_path):
    pid, eid = project_episode
    step_dir = tmp_path / pid / "checkpoints" / "episodes" / eid / "text_cleanup"
    step_dir.mkdir(parents=True)
    db = MagicMock()
    with pytest.raises(AppError) as exc_info:
        SnapshotService(db, pid, eid).restore(version="99990101_000000")
    assert exc_info.value.code == "snapshot.version_not_found"
