"""
Contract tests: execute_command_async return dict validates as ExecuteAsyncAcceptance (T02/T05).

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

from __future__ import annotations

from typing import Any

from unittest.mock import AsyncMock, MagicMock, patch

import pytest

from mcp_proxy_adapter.api.execute_async_contract import ExecuteAsyncAcceptance
from mcp_proxy_adapter.api.handlers_async import execute_command_async


def _make_request_with_delivery_manager(
    ws_id: str = "550e8400-e29b-41d4-a716-446655440000",
) -> Any:
    """Mock Request with app.state.ws_delivery_manager for execute_command_async."""
    app = MagicMock()
    manager = MagicMock()
    manager.issue_ws_id.return_value = ws_id
    manager.notify_terminal_delivery = AsyncMock()
    app.state.ws_delivery_manager = manager
    req = MagicMock()
    req.app = app
    req.state = MagicMock()
    return req


class TestExecuteAsyncAcceptanceContract:
    """Handler return shape must conform to ExecuteAsyncAcceptance schema."""

    @pytest.mark.asyncio
    async def test_acceptance_dict_model_validate_roundtrip(self) -> None:
        """Dict returned by execute_command_async validates as ExecuteAsyncAcceptance; no deliver_id."""
        mock_command_class = MagicMock()
        mock_result = MagicMock()
        mock_result.to_dict.return_value = {"success": True, "data": {}}
        mock_command_class.run = AsyncMock(return_value=mock_result)

        with patch("mcp_proxy_adapter.api.handlers_async.registry") as mock_registry:
            mock_registry.get_command.return_value = mock_command_class
            request = _make_request_with_delivery_manager()

            out = await execute_command_async(
                "echo", {"message": "roundtrip"}, None, None, request
            )

        model = ExecuteAsyncAcceptance.model_validate(out)
        assert model.accepted is True
        assert model.job_id is None
        assert model.ws_id
        assert isinstance(model.ws_id, str)
        assert len(model.ws_id) > 0
        assert model.delivery.mode == "ws"
        assert model.delivery.terminal_only is True
        assert "deliver_id" not in out
