"""Runtime logging tests for serve-mode MCP error paths."""

import logging
from pathlib import Path
from unittest.mock import patch

import pytest
from returns.result import Success

from anima.core.schemas import AgentState, AgentStateData, LifecycleType, TokenUsage
from anima.shell.mcp_serve import ServeMCPServer


@pytest.fixture
def server() -> ServeMCPServer:
    """Create a ServeMCPServer instance."""
    return ServeMCPServer(host="127.0.0.1", port=8420)


@pytest.fixture
def sample_agent_state() -> AgentStateData:
    """Create sample agent state data."""
    return AgentStateData(
        instance_id="inst_test123",
        trace_id="trace_abc",
        persona_name="test_persona",
        spec_id="spec_001",
        spec_digest="abc123",
        model="test-model",
        state=AgentState.running,
        lifecycle=LifecycleType.ephemeral,
        parent_id=None,
        children=[],
        depth=0,
        max_depth=3,
        pid=12345,
        mcp_socket="/tmp/anima/agents/inst_test123/mcp.sock",
        created_at="2024-01-01T00:00:00Z",
        updated_at="2024-01-01T00:00:00Z",
        token_usage=TokenUsage(),
        tools_called=[],
        current_turn=0,
        max_turns=100,
        budget_total=100000,
        grace_budget=1000,
        error=None,
        result_ref=None,
    )


class TestServeLoggingRuntime:
    """Runtime-oriented checks for logging behavior in error paths."""

    @pytest.mark.asyncio
    async def test_handle_list_logs_timestamp_parse_failure(
        self,
        server: ServeMCPServer,
        sample_agent_state: AgentStateData,
        caplog: pytest.LogCaptureFixture,
    ) -> None:
        """Malformed created_at timestamp triggers debug log."""
        sample_agent_state.created_at = "not-a-timestamp"

        with (
            patch("anima.shell.mcp_serve.list_agents") as mock_list,
            patch("anima.shell.mcp_serve.check_and_reap_stale_agents") as mock_reap,
        ):
            mock_list.return_value = Success([sample_agent_state])
            mock_reap.return_value = [sample_agent_state]

            with caplog.at_level(logging.DEBUG, logger="anima.shell.mcp_serve"):
                await server._handle_list()

        assert any(
            "Failed to parse created_at timestamp" in record.message
            for record in caplog.records
        )

    @pytest.mark.asyncio
    async def test_handle_collect_logs_result_file_decode_error(
        self,
        server: ServeMCPServer,
        sample_agent_state: AgentStateData,
        tmp_path: Path,
        caplog: pytest.LogCaptureFixture,
    ) -> None:
        """Invalid result.json payload triggers debug log in collect path."""
        sample_agent_state.state = AgentState.completed
        agent_dir = tmp_path / sample_agent_state.instance_id
        agent_dir.mkdir(parents=True)
        (agent_dir / "result.json").write_text("{invalid json")

        with (
            patch("anima.shell.mcp_serve.find_agent_by_prefix") as mock_find,
            patch("anima.shell.mcp_serve.get_agent_dir") as mock_dir,
        ):
            mock_find.return_value = Success(sample_agent_state)
            mock_dir.return_value = agent_dir

            with caplog.at_level(logging.DEBUG, logger="anima.shell.mcp_serve"):
                await server._handle_collect(sample_agent_state.instance_id)

        assert any(
            "Failed to read result file" in record.message for record in caplog.records
        )

    @pytest.mark.asyncio
    async def test_read_logs_from_file_logs_malformed_lines(
        self,
        server: ServeMCPServer,
        sample_agent_state: AgentStateData,
        tmp_path: Path,
        caplog: pytest.LogCaptureFixture,
    ) -> None:
        """Malformed log.jsonl lines are skipped with debug logging."""
        agent_dir = tmp_path / sample_agent_state.instance_id
        agent_dir.mkdir(parents=True)
        (agent_dir / "log.jsonl").write_text(
            '{"event": "ok"}\n{bad-json-line}\n{"event": "ok2"}\n'
        )

        with patch("anima.shell.state.get_agent_dir") as mock_dir:
            mock_dir.return_value = agent_dir

            with caplog.at_level(logging.DEBUG, logger="anima.shell.mcp_serve"):
                result = await server._read_logs_from_file(
                    sample_agent_state.instance_id,
                    tail=None,
                    agent_state=sample_agent_state,
                )

        assert result["count"] == 2
        assert any(
            "Skipping malformed log line" in record.message for record in caplog.records
        )
