"""Tests for MCP Server integration.

Tests cover:
- Server creation and lifespan
- Tool registration
- Resource registration
- Prompt registration
"""
from __future__ import annotations

from unittest.mock import MagicMock, patch
import pytest


# =============================================================================
# Server Tests
# =============================================================================

class TestServerCreation:
    """Tests for MCP server creation."""

    def test_server_module_imports(self):
        """Test that server module can be imported."""
        from src.server import mcp, main
        assert mcp is not None
        assert callable(main)

    def test_server_has_name(self):
        """Test that server has correct name."""
        from src.server import mcp
        assert mcp.name == "meta-ads-mcp"

    def test_main_uses_configured_http_transport(self, monkeypatch):
        """Test that TRANSPORT_TYPE=http maps to streamable-http."""
        monkeypatch.setenv("TRANSPORT_TYPE", "http")
        monkeypatch.setenv("HOSTED_MODE", "true")
        monkeypatch.setenv("AUTH_BROKER_URL", "https://auth.example.com")
        monkeypatch.setenv("AUTH_BROKER_API_KEY", "test-admin-api-key")
        monkeypatch.setenv("JWT_PUBLIC_KEY", "test-jwt-shared-secret")
        from src import server

        with patch.object(server.mcp, "run") as mock_run:
            server.main()

        mock_run.assert_called_once_with(transport="streamable-http")


class TestToolRegistration:
    """Tests for tool registration."""

    def test_tools_module_imports(self):
        """Test that tools module can be imported."""
        from src.tools import register_all_tools
        assert callable(register_all_tools)

    def test_tool_registration_no_error(self):
        """Test that tools can be registered without error."""
        from mcp.server.fastmcp import FastMCP
        from src.tools import register_all_tools
        
        test_mcp = FastMCP("test")
        # Should not raise
        register_all_tools(test_mcp)

    def test_all_tool_modules_import(self):
        """Test that all tool modules can be imported."""
        tool_modules = [
            "src.tools.ad_management",
            "src.tools.advantage",
            "src.tools.audiences",
            "src.tools.insights",
            "src.tools.creative",
            "src.tools.conversion",
            "src.tools.fraud",
            "src.tools.monitoring",
            "src.tools.tactical",
            "src.tools.reporting",
            "src.tools.roas",
            "src.tools.threads",
            "src.tools.whatsapp_flows",
            "src.tools.reels",
            "src.tools.ccco",
            "src.tools.signals",
        ]
        
        import importlib
        for module_name in tool_modules:
            try:
                module = importlib.import_module(module_name)
                assert hasattr(module, "get_tools"), f"{module_name} missing get_tools"
            except ImportError as e:
                pytest.fail(f"Failed to import {module_name}: {e}")


class TestResourceRegistration:
    """Tests for MCP resource registration."""

    def test_resources_module_imports(self):
        """Test that resources module can be imported."""
        from src.resources import register_resources
        assert callable(register_resources)

    def test_resource_registration_no_error(self):
        """Test that resources can be registered without error."""
        from mcp.server.fastmcp import FastMCP
        from src.resources import register_resources
        
        test_mcp = FastMCP("test")
        # Should not raise
        register_resources(test_mcp)


class TestPromptRegistration:
    """Tests for MCP prompt registration."""

    def test_prompts_module_imports(self):
        """Test that prompts module can be imported."""
        from src.prompts import register_prompts
        assert callable(register_prompts)

    def test_prompt_registration_no_error(self):
        """Test that prompts can be registered without error."""
        from mcp.server.fastmcp import FastMCP
        from src.prompts import register_prompts
        
        test_mcp = FastMCP("test")
        # Should not raise
        register_prompts(test_mcp)


# =============================================================================
# Lifespan Tests
# =============================================================================

class TestLifespan:
    """Tests for server lifespan management."""

    @pytest.mark.asyncio
    async def test_app_context_creation(self):
        """Test that AppContext can be created."""
        from src.server import AppContext
        
        mock_client = MagicMock()
        ctx = AppContext(client=mock_client)
        
        assert ctx.client is mock_client

    @pytest.mark.asyncio
    async def test_lifespan_function_exists(self):
        """Test that lifespan function is defined."""
        from src.server import app_lifespan
        
        # Lifespan should be a callable
        assert callable(app_lifespan)


# =============================================================================
# Full Integration Tests
# =============================================================================

class TestFullIntegration:
    """Integration tests for the complete server."""

    def test_server_can_start_dry_run(self):
        """Test that server can be configured (dry run - no actual start)."""
        from src.server import mcp
        
        # Server should be configured
        assert mcp.name == "meta-ads-mcp"

    def test_all_modules_import_cleanly(self):
        """Test that all major modules import without error."""
        modules_to_test = [
            "src.server",
            "src.meta_client",
            "src.schemas",
            "src.errors",
            "src.logging",
            "src.cache",
            "src.rate_limiter",
            "src.resources",
            "src.prompts",
        ]
        
        import importlib
        for module_name in modules_to_test:
            try:
                importlib.import_module(module_name)
            except ImportError as e:
                pytest.fail(f"Failed to import {module_name}: {e}")
