"""Ping interactions against the low-level Server, driven through the public Client API."""

import mcp_types as types
import pytest
from inline_snapshot import snapshot
from mcp_types import CallToolResult, EmptyResult, TextContent

from mcp.server import Server, ServerRequestContext
from tests.interaction._connect import Connect
from tests.interaction._requirements import requirement

pytestmark = pytest.mark.anyio


@requirement("lifecycle:ping")
@requirement("ping:client-to-server")
async def test_client_ping_returns_empty_result(connect: Connect) -> None:
    """A client ping is answered with an empty result, even by a server with no handlers."""
    server = Server("silent")

    async with connect(server) as client:
        result = await client.send_ping()  # pyright: ignore[reportDeprecated]

    assert result == snapshot(EmptyResult())


@requirement("lifecycle:ping")
@requirement("ping:server-to-client")
async def test_server_ping_returns_empty_result(connect: Connect) -> None:
    """A server-initiated ping sent while a request is in flight is answered by the client.

    The tool returns the type of the ping response, proving the round trip completed inside
    the handler before the tool result was produced.
    """

    async def list_tools(
        ctx: ServerRequestContext, params: types.PaginatedRequestParams | None
    ) -> types.ListToolsResult:
        return types.ListToolsResult(
            tools=[types.Tool(name="ping_back", description="Ping the client.", input_schema={"type": "object"})]
        )

    async def call_tool(ctx: ServerRequestContext, params: types.CallToolRequestParams) -> CallToolResult:
        assert params.name == "ping_back"
        pong = await ctx.session.send_ping()
        return CallToolResult(content=[TextContent(text=type(pong).__name__)])

    server = Server("pinger", on_list_tools=list_tools, on_call_tool=call_tool)

    async with connect(server) as client:
        result = await client.call_tool("ping_back", {})

    assert result == snapshot(CallToolResult(content=[TextContent(text="EmptyResult")]))
