"""Integration tests for the language handler system.

These tests verify the integration between handlers, registry, and dispatcher.
Each test uses a fresh registry instance to avoid test pollution.
"""

import pytest

import core.dispatcher
from core.dispatcher import get_handler_for_feature, get_handler_for_language
from core.errors import HandlerNotImplementedError, LanguageNotFoundError
from core.languages.js_ts.handler import JSTypeScriptHandler
from core.languages.python.handler import PythonHandler
from core.registry import LanguageRegistry


@pytest.fixture
def fresh_registry() -> LanguageRegistry:
    """Create a fresh LanguageRegistry instance with handlers registered."""
    registry = LanguageRegistry()

    # Register handlers
    registry.register("python", PythonHandler)
    registry.register("js_ts", JSTypeScriptHandler)

    return registry


class TestPythonHandler:
    """Test PythonHandler instantiation and capabilities."""

    def test_python_handler_instantiation(self) -> None:
        """Test PythonHandler instantiation and verify all capability flags."""
        handler = PythonHandler()

        # Verify capability flags
        assert handler.supports_testgen is True
        assert handler.supports_optimizer is True
        assert handler.supports_code_repair is True
        assert handler.supports_jit_rewrite is True
        assert handler.supports_optimization_review is True
        assert handler.supports_explanations is True

        # Verify language
        assert handler.language == "python"


class TestJSTypeScriptHandler:
    """Test JSTypeScriptHandler instantiation and capabilities."""

    def test_js_typescript_handler_instantiation(self) -> None:
        """Test JSTypeScriptHandler instantiation and verify capability flags."""
        handler = JSTypeScriptHandler()

        # Verify capability flags
        assert handler.supports_testgen is True
        assert handler.supports_optimizer is True
        assert handler.supports_code_repair is False
        assert handler.supports_jit_rewrite is False
        assert handler.supports_optimization_review is False
        assert handler.supports_explanations is False

        # Verify language
        assert handler.language == "js_ts"


class TestRegistry:
    """Test registry registration and retrieval."""

    def test_registry_registration(self, fresh_registry: LanguageRegistry) -> None:
        """Test that handlers are properly registered in the registry."""
        # Get handler for Python
        python_handler_class = fresh_registry.get_handler("python")
        assert python_handler_class is PythonHandler
        python_instance = python_handler_class()
        assert isinstance(python_instance, PythonHandler)

        # Get handler for JS/TS
        js_ts_handler_class = fresh_registry.get_handler("js_ts")
        assert js_ts_handler_class is JSTypeScriptHandler
        js_ts_instance = js_ts_handler_class()
        assert isinstance(js_ts_instance, JSTypeScriptHandler)

    def test_registry_unknown_language_raises_error(self, fresh_registry: LanguageRegistry) -> None:
        """Test that requesting an unknown language raises LanguageNotFoundError."""
        with pytest.raises(LanguageNotFoundError) as exc_info:
            fresh_registry.get_handler("rust")

        assert "rust" in str(exc_info.value)
        assert "not found" in str(exc_info.value)

    def test_list_available(self, fresh_registry: LanguageRegistry) -> None:
        """Test that list_available returns the correct languages."""
        available = fresh_registry.list_available()
        assert isinstance(available, list)
        assert "python" in available
        assert "js_ts" in available
        assert len(available) == 2


class TestDispatcher:
    """Test dispatcher functions."""

    def test_get_handler_for_language(self, fresh_registry: LanguageRegistry, monkeypatch: pytest.MonkeyPatch) -> None:
        """Test get_handler_for_language returns a handler instance."""
        # Monkeypatch the global registry to use our fresh one
        monkeypatch.setattr(core.dispatcher, "registry", fresh_registry)

        # Test getting Python handler
        python_handler = get_handler_for_language("python")
        assert isinstance(python_handler, PythonHandler)

        # Test getting JS/TS handler
        js_handler = get_handler_for_language("js_ts")
        assert isinstance(js_handler, JSTypeScriptHandler)

    def test_get_handler_for_feature(self, fresh_registry: LanguageRegistry, monkeypatch: pytest.MonkeyPatch) -> None:
        """Test get_handler_for_feature with valid and invalid feature combinations."""
        # Monkeypatch the global registry to use our fresh one
        monkeypatch.setattr(core.dispatcher, "registry", fresh_registry)

        # Test valid feature: Python with testgen
        python_testgen = get_handler_for_feature("python", "testgen")
        assert isinstance(python_testgen, PythonHandler)

        # Test valid feature: JS/TS with testgen
        js_testgen = get_handler_for_feature("js_ts", "testgen")
        assert isinstance(js_testgen, JSTypeScriptHandler)

        # Test invalid feature: JS/TS with code_repair (not supported)
        with pytest.raises(HandlerNotImplementedError) as exc_info:
            get_handler_for_feature("js_ts", "code_repair")

        assert "js_ts" in str(exc_info.value)
        assert "code_repair" in str(exc_info.value)
        assert "does not support" in str(exc_info.value)
