"""End-to-end tests for SDK MCP (inline) tools with real Claude API calls.

These tests verify that SDK-created MCP tools work correctly through the full stack,
focusing on tool execution mechanics rather than specific tool functionality.
"""

from typing import Any

import pytest

from clawd_code_sdk import ClaudeAgentOptions, ClaudeSDKClient, create_sdk_mcp_server, tool


@pytest.mark.e2e
async def test_sdk_mcp_tool_execution():
    """Test that SDK MCP tools can be called and executed with allowed_tools."""
    executions = []

    @tool("echo", "Echo back the input text", {"text": str})
    async def echo_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Echo back whatever text is provided."""
        executions.append("echo")
        return {"content": [{"type": "text", "text": f"Echo: {args['text']}"}]}

    server = create_sdk_mcp_server(name="test", version="1.0.0", tools=[echo_tool])
    options = ClaudeAgentOptions(mcp_servers={"test": server}, allowed_tools=["mcp__test__echo"])

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Call the mcp__test__echo tool with any text")

        async for _message in client.receive_response():
            pass  # Just consume messages

    # Check if the actual Python function was called
    assert "echo" in executions, "Echo tool function was not executed"


@pytest.mark.e2e
async def test_sdk_mcp_permission_enforcement():
    """Test that disallowed_tools prevents SDK MCP tool execution."""
    executions = []

    @tool("echo", "Echo back the input text", {"text": str})
    async def echo_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Echo back whatever text is provided."""
        executions.append("echo")
        return {"content": [{"type": "text", "text": f"Echo: {args['text']}"}]}

    @tool("greet", "Greet a person by name", {"name": str})
    async def greet_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Greet someone by name."""
        executions.append("greet")
        return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

    server = create_sdk_mcp_server(name="test", version="1.0.0", tools=[echo_tool, greet_tool])
    options = ClaudeAgentOptions(
        mcp_servers={"test": server},
        disallowed_tools=["mcp__test__echo"],  # Block echo tool
        allowed_tools=["mcp__test__greet"],  # But allow greet
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query("Use the echo tool to echo 'test' and use greet tool to greet 'Alice'")

        async for _message in client.receive_response():
            pass  # Just consume messages

    # Check actual function executions
    assert "echo" not in executions, "Disallowed echo tool was executed"
    assert "greet" in executions, "Allowed greet tool was not executed"


@pytest.mark.e2e
async def test_sdk_mcp_multiple_tools():
    """Test that multiple SDK MCP tools can be called in sequence."""
    executions = []

    @tool("echo", "Echo back the input text", {"text": str})
    async def echo_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Echo back whatever text is provided."""
        executions.append("echo")
        return {"content": [{"type": "text", "text": f"Echo: {args['text']}"}]}

    @tool("greet", "Greet a person by name", {"name": str})
    async def greet_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Greet someone by name."""
        executions.append("greet")
        return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

    server = create_sdk_mcp_server(name="multi", version="1.0.0", tools=[echo_tool, greet_tool])
    options = ClaudeAgentOptions(
        mcp_servers={"multi": server},
        allowed_tools=["mcp__multi__echo", "mcp__multi__greet"],
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query(
            "Call mcp__multi__echo with text='test' and mcp__multi__greet with name='Bob'"
        )

        async for _message in client.receive_response():
            pass  # Just consume messages

    # Both tools should have been executed
    assert "echo" in executions, "Echo tool was not executed"
    assert "greet" in executions, "Greet tool was not executed"


@pytest.mark.e2e
async def test_sdk_mcp_without_permissions():
    """Test SDK MCP tool behavior without explicit allowed_tools."""
    executions = []

    @tool("echo", "Echo back the input text", {"text": str})
    async def echo_tool(args: dict[str, Any]) -> dict[str, Any]:
        """Echo back whatever text is provided."""
        executions.append("echo")
        return {"content": [{"type": "text", "text": f"Echo: {args['text']}"}]}

    server = create_sdk_mcp_server(name="noperm", version="1.0.0", tools=[echo_tool])
    # No allowed_tools specified
    options = ClaudeAgentOptions(mcp_servers={"noperm": server})
    async with ClaudeSDKClient(options=options) as client:
        await client.query("Call the mcp__noperm__echo tool")

        async for _message in client.receive_response():
            pass  # Just consume messages

    assert "echo" not in executions, "SDK MCP tool was executed"
