"""Additional tests to ensure protocol definition coverage."""

import inspect

import pytest

from augint_library.protocols import (
    AdvancedProcessor,
    CacheProvider,
    ConfigurableClient,
    DataProcessor,
    EventHandler,
    ProcessingResult,
)


@pytest.mark.unit
def test_processing_result_method_signatures() -> None:
    """Test ProcessingResult protocol method signatures."""
    # Get all methods/properties
    methods = [name for name in dir(ProcessingResult) if not name.startswith("_")]

    expected_methods = ["success", "data", "error", "metadata"]
    for method in expected_methods:
        assert method in methods, f"Missing method: {method}"

    # Test type hints exist (properties may not have easily accessible type hints, but protocols define them)
    # Type hints are defined in the protocol method signatures themselves


@pytest.mark.unit
def test_data_processor_method_signatures() -> None:
    """Test DataProcessor protocol method signatures."""
    # Check method existence
    assert hasattr(DataProcessor, "process")
    assert hasattr(DataProcessor, "batch_process")

    # Check process method signature
    process_sig = inspect.signature(DataProcessor.process)
    param_names = list(process_sig.parameters.keys())

    expected_params = ["self", "data", "timeout", "retries", "validate"]
    for param in expected_params:
        assert param in param_names, f"Missing parameter: {param}"


@pytest.mark.unit
def test_configurable_client_method_signatures() -> None:
    """Test ConfigurableClient protocol method signatures."""
    assert hasattr(ConfigurableClient, "get")
    assert hasattr(ConfigurableClient, "post")

    # Check get method signature
    get_sig = inspect.signature(ConfigurableClient.get)
    assert "self" in get_sig.parameters
    assert "endpoint" in get_sig.parameters


@pytest.mark.unit
def test_event_handler_method_signatures() -> None:
    """Test EventHandler protocol method signatures."""
    assert hasattr(EventHandler, "handle_event")
    assert hasattr(EventHandler, "can_handle")

    # Check handle_event signature
    handle_sig = inspect.signature(EventHandler.handle_event)
    expected_params = ["self", "event_type", "event_data", "priority"]
    param_names = list(handle_sig.parameters.keys())

    for param in expected_params:
        assert param in param_names, f"Missing parameter: {param}"


@pytest.mark.unit
def test_cache_provider_method_signatures() -> None:
    """Test CacheProvider protocol method signatures."""
    methods = ["get", "set", "delete", "clear"]

    for method_name in methods:
        assert hasattr(CacheProvider, method_name), f"Missing method: {method_name}"

    # Test set method signature (has keyword-only ttl parameter)
    set_sig = inspect.signature(CacheProvider.set)
    param_names = list(set_sig.parameters.keys())

    expected_params = ["self", "key", "value", "ttl"]
    for param in expected_params:
        assert param in param_names, f"Missing parameter: {param}"


@pytest.mark.unit
def test_advanced_processor_composition() -> None:
    """Test AdvancedProcessor protocol composition."""
    # Should have methods from both DataProcessor and EventHandler
    data_processor_methods = ["process", "batch_process"]
    event_handler_methods = ["handle_event", "can_handle"]
    advanced_methods = ["process_with_events"]

    all_expected = data_processor_methods + event_handler_methods + advanced_methods

    for method_name in all_expected:
        assert hasattr(AdvancedProcessor, method_name), f"Missing method: {method_name}"


@pytest.mark.unit
def test_protocol_docstrings_exist() -> None:
    """Test that all protocols have docstrings."""
    protocols = [
        ProcessingResult,
        DataProcessor,
        ConfigurableClient,
        EventHandler,
        CacheProvider,
        AdvancedProcessor,
    ]

    for protocol in protocols:
        assert protocol.__doc__ is not None, f"Protocol {protocol.__name__} missing docstring"
        assert len(protocol.__doc__.strip()) > 0, (
            f"Protocol {protocol.__name__} has empty docstring"
        )


@pytest.mark.unit
def test_protocol_method_docstrings() -> None:
    """Test that protocol methods have docstrings."""
    # Test a few key methods have docstrings
    assert DataProcessor.process.__doc__ is not None
    assert EventHandler.handle_event.__doc__ is not None
    assert CacheProvider.get.__doc__ is not None
    assert AdvancedProcessor.process_with_events.__doc__ is not None


@pytest.mark.unit
def test_protocol_inheritance_structure() -> None:
    """Test protocol inheritance relationships."""
    # AdvancedProcessor should inherit from both DataProcessor and EventHandler
    # For protocols, inheritance is more about composition - test that it has methods from both

    # Check it has DataProcessor methods
    assert hasattr(AdvancedProcessor, "process")
    assert hasattr(AdvancedProcessor, "batch_process")

    # Check it has EventHandler methods
    assert hasattr(AdvancedProcessor, "handle_event")
    assert hasattr(AdvancedProcessor, "can_handle")

    # Check it has its own method
    assert hasattr(AdvancedProcessor, "process_with_events")

    # Test that it's recognized as runtime checkable
    assert hasattr(AdvancedProcessor, "_is_runtime_protocol")
