"""Step definitions for features/tdd_mcp_error_content_key.feature.

TDD issue-capture scenario for #2158: MCPToolAdapter.invoke() must extract
error messages from content[0].text per MCP 1.4.0 protocol.
"""

from __future__ import annotations

from typing import Any

from behave import given, then
from behave.runner import Context

from cleveragents.mcp.adapter import MCPServerConfig, MCPToolAdapter
from features.mocks.mock_mcp_transport import MockMCPTransport


class _MCP14ErrorTransport(MockMCPTransport):
    """Mock transport that returns MCP 1.4.0-compliant error responses.

    Returns ``{"isError": True, "content": [{"type": "text", "text": "..."}]}``
    instead of the non-standard ``{"isError": True, "error": "..."}`` format.
    """

    def __init__(self, tool_name: str, error_text: str) -> None:
        tools = [
            {
                "name": tool_name,
                "description": f"Mock tool {tool_name}",
                "inputSchema": {},
            }
        ]
        super().__init__(tools=tools)
        self._mcp14_error_tool = tool_name
        self._mcp14_error_text = error_text

    def call(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
        if method == "tools/call":
            tool_name = params.get("name", "")
            if tool_name == self._mcp14_error_tool:
                return {
                    "isError": True,
                    "content": [{"type": "text", "text": self._mcp14_error_text}],
                }
        return super().call(method, params)


@given(
    'a connected MCP adapter with a tool returning MCP 1.4.0 content-based error "{tool_name}"'
)
def step_mcp14_error_tool(context: Context, tool_name: str) -> None:
    """Set up a connected MCP adapter whose tool returns a MCP 1.4.0 content-based error."""
    transport = _MCP14ErrorTransport(
        tool_name=tool_name,
        error_text="File not found: /path/to/file",
    )
    config = MCPServerConfig(name="test-server", transport="stdio", command="echo")
    context.mcp_adapter = MCPToolAdapter(config=config, transport=transport)
    context.mcp_adapter.connect()
    context.mcp_adapter.discover_tools()


@then('the invocation error should contain "{expected}"')
def step_invoke_error_contains(context: Context, expected: str) -> None:
    """Assert the invocation error message contains the expected substring."""
    result = context.mcp_invoke_result
    assert result is not None, "No invocation result found"
    assert result.error is not None, "Expected an error but got None"
    assert expected in result.error, (
        f"Expected error to contain {expected!r}, got: {result.error!r}"
    )
