"""
Integration tests for MCP tools in the reply engine.

These tests require more complex setup and may not run in basic CI environments.
They can be run locally or in development environments with git hooks.
"""

import pytest
from unittest.mock import Mock, patch


@pytest.mark.integration
def test_mcp_tools_integrated_with_reply_engine():
    """Test that MCP tools are properly integrated with the reply engine's tool discovery."""
    from jarvis.tools.registry import discover_mcp_tools, generate_tools_description, BUILTIN_TOOLS

    # Mock MCP client
    class FakeMCPClient:
        def __init__(self, config):
            pass

        def list_tools(self, server_name):
            if server_name == "test-server":
                return [
                    {"name": "tool1", "description": "Test tool 1"},
                    {"name": "tool2", "description": "Test tool 2"}
                ]
            return []

    with patch('jarvis.tools.registry.MCPClient', FakeMCPClient):
        # Test discovery
        mcps_config = {"test-server": {"command": "fake"}}
        mcp_tools, _errors = discover_mcp_tools(mcps_config)

        # Test tool registration (simulate what reply engine does)
        allowed_tools = list(BUILTIN_TOOLS.keys())
        for mcp_tool_name in mcp_tools.keys():
            if mcp_tool_name not in allowed_tools:
                allowed_tools.append(mcp_tool_name)

        # Test tool descriptions include MCP tools
        description = generate_tools_description(allowed_tools, mcp_tools)
        
        # Assertions
        assert "test-server__tool1" in allowed_tools
        assert "test-server__tool2" in allowed_tools
        assert "test-server__tool1" in description
        assert "test-server__tool2" in description


@pytest.mark.integration 
def test_mcp_tool_execution_in_context():
    """Test MCP tool execution with proper context and error handling."""
    from jarvis.tools.registry import run_tool_with_retries, ToolExecutionResult
    
    class MockDB:
        pass
    
    class MockConfig:
        def __init__(self):
            self.mcps = {"test-server": {"command": "fake"}}
            self.voice_debug = False
    
    # Mock successful execution
    class FakeMCPClient:
        def __init__(self, config):
            pass
            
        def invoke_tool(self, server_name, tool_name, arguments):
            return {"text": f"Executed {tool_name} on {server_name}", "isError": False}
    
    with patch('jarvis.tools.registry.MCPClient', FakeMCPClient):
        result = run_tool_with_retries(
            db=MockDB(),
            cfg=MockConfig(),
            tool_name="test-server__example_tool",
            tool_args={"param": "value"},
            system_prompt="test",
            original_prompt="test",
            redacted_text="test",
            max_retries=0
        )
        
        assert result.success is True
        assert "Executed example_tool on test-server" in result.reply_text


@pytest.mark.integration
def test_mcp_error_handling_in_context():
    """Test that MCP errors are properly handled in execution context."""
    from jarvis.tools.registry import run_tool_with_retries
    
    class MockDB:
        pass
    
    class MockConfig:
        def __init__(self):
            self.mcps = {"test-server": {"command": "fake"}}
            self.voice_debug = False
    
    # Mock failing execution
    class FailingMCPClient:
        def __init__(self, config):
            pass
            
        def invoke_tool(self, server_name, tool_name, arguments):
            return {"text": "Tool failed", "isError": True}
    
    with patch('jarvis.tools.registry.MCPClient', FailingMCPClient):
        result = run_tool_with_retries(
            db=MockDB(),
            cfg=MockConfig(),
            tool_name="test-server__failing_tool",
            tool_args={},
            system_prompt="test",
            original_prompt="test", 
            redacted_text="test",
            max_retries=0
        )
        
        assert result.success is False
        assert result.error_message == "Tool failed"
