from __future__ import annotations

from typing import TYPE_CHECKING, cast

import pytest

from mcp_vm_blackbox.vagrant_tools import _mark_run_complete

if TYPE_CHECKING:
    from pathlib import Path

    from fastmcp import Context


class _NoSessionContext:
    async def set_state(self, key: str, value: str) -> None:
        del key, value
        raise RuntimeError(
            "session_id is not available because no session exists. This typically means you're outside a request context."
        )

    async def enable_components(self, *, tags: set[str]) -> None:
        del tags
        raise AssertionError("enable_components should not be called after set_state session failure")


class _OtherFailureContext:
    async def set_state(self, key: str, value: str) -> None:
        del key, value
        raise RuntimeError("different failure")

    async def enable_components(self, *, tags: set[str]) -> None:
        del tags


@pytest.mark.asyncio
async def test_mark_run_complete_persists_file_without_session(tmp_path: Path) -> None:
    await _mark_run_complete("vm-a/scenario-a", cast("Context", _NoSessionContext()), store_root=tmp_path)

    status_file = tmp_path / "run-status" / "vm-a" / "scenario-a.json"
    assert status_file.exists()
    assert status_file.read_text() == '{"status": "completed"}'


@pytest.mark.asyncio
async def test_mark_run_complete_reraises_unexpected_runtime_error(tmp_path: Path) -> None:
    with pytest.raises(RuntimeError, match="different failure"):
        await _mark_run_complete("vm-a/scenario-a", cast("Context", _OtherFailureContext()), store_root=tmp_path)
