"""Tests for CursorAdapter and sanitize_windows."""

from __future__ import annotations

import pytest
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock

from vastian.bridges.cursor_bridge.direct import CursorAdapter, sanitize_windows


class TestSanitizeWindows:
    def test_replaces_arrows(self) -> None:
        assert sanitize_windows("\u2192 next") == "-> next"
        assert sanitize_windows("\u2190 back") == "<- back"

    def test_replaces_quotes(self) -> None:
        assert sanitize_windows("\u201cHello\u201d") == '"Hello"'
        assert sanitize_windows("\u2018hi\u2019") == "'hi'"

    def test_replaces_bullets(self) -> None:
        assert sanitize_windows("\u2022 item") == "* item"

    def test_replaces_check_marks(self) -> None:
        assert sanitize_windows("\u2713 done") == "[x] done"

    def test_strips_remaining_non_cp1252(self) -> None:
        # Emoji should be replaced, not crash
        result = sanitize_windows("Hello \U0001f600 world")
        assert "Hello" in result
        assert "world" in result
        # Should not raise
        result.encode("cp1252")

    def test_passthrough_ascii(self) -> None:
        text = "Hello, world! 123 -- done."
        assert sanitize_windows(text) == text


class TestCursorAdapter:
    @pytest.fixture
    def mock_orch(self) -> MagicMock:
        orch = MagicMock()
        orch.handle_user_message_direct = AsyncMock(return_value="Agent response here")
        return orch

    @pytest.fixture
    def adapter(self, mock_orch: MagicMock) -> CursorAdapter:
        return CursorAdapter(mock_orch)

    @pytest.mark.asyncio
    async def test_query_agent(self, adapter: CursorAdapter, mock_orch: MagicMock) -> None:
        result = await adapter.query_agent("henry", "What is your role?")
        mock_orch.handle_user_message_direct.assert_called_once_with(
            content="What is your role?", agent_id="henry"
        )
        assert result == "Agent response here"

    @pytest.mark.asyncio
    async def test_query_agents_parallel(self, adapter: CursorAdapter) -> None:
        results = await adapter.query_agents(["henry", "liam"], "Status?")
        assert isinstance(results, dict)
        assert "henry" in results
        assert "liam" in results

    @pytest.mark.asyncio
    async def test_query_agents_handles_error(self, mock_orch: MagicMock) -> None:
        async def side_effect(content, agent_id):
            if agent_id == "badagent":
                raise RuntimeError("Agent exploded")
            return "OK"

        mock_orch.handle_user_message_direct = AsyncMock(side_effect=side_effect)
        adapter = CursorAdapter(mock_orch)
        results = await adapter.query_agents(["henry", "badagent"], "Hello")
        assert results["henry"] == "OK"
        assert "[Error:" in results["badagent"]

    @pytest.mark.asyncio
    async def test_quiz_agents_prefixes_prompt(
        self, adapter: CursorAdapter, mock_orch: MagicMock
    ) -> None:
        await adapter.quiz_agents(["henry"], "Q1: What phase?\nQ2: What wave?")
        call_args = mock_orch.handle_user_message_direct.call_args
        assert "Answer each question" in call_args.kwargs.get(
            "content", call_args[1].get("content", "")
        )

    @pytest.mark.asyncio
    async def test_present_returns_structured_dict(self, adapter: CursorAdapter) -> None:
        result = await adapter.present(["henry", "liam"], "Phase Mercury plan", topic="Mercury")
        assert result["topic"] == "Mercury"
        assert result["agent_count"] == 2
        assert "responses" in result
        assert "timestamp" in result

    def test_persist_briefs_creates_files(self, adapter: CursorAdapter, temp_dir: Path) -> None:
        # Override the project root to use temp dir
        adapter._project_root = temp_dir
        results = {"henry": "My response", "liam": "Liam response"}
        paths = adapter.persist_briefs(results, "Mercury Phase")
        assert len(paths) == 2
        for p in paths:
            assert Path(p).exists()
            content = Path(p).read_text(encoding="utf-8")
            assert "Mercury Phase" in content
