"""Typed Protocol interfaces for all spec-defined extension points.

Defines ``@runtime_checkable`` Protocol classes for each of the 30
extension point categories.  Each Protocol specifies the minimum
interface that a plugin implementation must satisfy.

Based on ``docs/specification.md`` Extension Points Summary and
issue #939.

ISSUES CLOSED: #939
"""

from __future__ import annotations

from collections.abc import Mapping, Sequence
from typing import Any, Protocol, runtime_checkable

# ---------------------------------------------------------------------------
# Context extension protocols (12 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class ContextStrategyExtension(Protocol):
    """Protocol for context strategy plugins."""

    @property
    def name(self) -> str: ...

    def can_handle(self, request: Mapping[str, Any]) -> float: ...

    def assemble(self, fragments: Sequence[Any], budget: Any) -> Sequence[Any]: ...


@runtime_checkable
class ContextPipelineComponentExtension(Protocol):
    """Protocol for pipeline stage components.

    Covers all 10 pipeline phases: strategy_selector,
    budget_allocator, strategy_executor, deduplicator,
    depth_resolver, scorer, packer, orderer,
    preamble_generator, skeleton_compressor.
    """

    @property
    def component_name(self) -> str: ...

    def process(
        self, fragments: Sequence[Any], context: Mapping[str, Any]
    ) -> Sequence[Any]: ...


@runtime_checkable
class ContextStorageBackendExtension(Protocol):
    """Protocol for context storage backends (text, vector, graph)."""

    @property
    def backend_type(self) -> str: ...

    def store(self, key: str, data: Any) -> None: ...

    def retrieve(self, key: str) -> Any: ...


# ---------------------------------------------------------------------------
# Output extension protocols (3 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class OutputRendererExtension(Protocol):
    """Protocol for output renderer plugins."""

    @property
    def format_name(self) -> str: ...

    def render(self, data: Any) -> str: ...


@runtime_checkable
class OutputMaterializerExtension(Protocol):
    """Protocol for output materializer plugins."""

    @property
    def target_type(self) -> str: ...

    def materialize(self, content: str, destination: str) -> None: ...


@runtime_checkable
class OutputFormatExtension(Protocol):
    """Protocol for custom output format plugins."""

    @property
    def format_id(self) -> str: ...

    def serialize(self, data: Any) -> str: ...

    def deserialize(self, raw: str) -> Any: ...


# ---------------------------------------------------------------------------
# Validation extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class ValidationRunnerExtension(Protocol):
    """Protocol for validation runner plugins."""

    @property
    def runner_name(self) -> str: ...

    def validate(self, target: Any) -> Sequence[Any]: ...


@runtime_checkable
class ValidationRuleProviderExtension(Protocol):
    """Protocol for validation rule provider plugins."""

    @property
    def provider_name(self) -> str: ...

    def get_rules(self) -> Sequence[Any]: ...


# ---------------------------------------------------------------------------
# Tool extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class ToolProviderExtension(Protocol):
    """Protocol for tool provider plugins."""

    @property
    def provider_name(self) -> str: ...

    def list_tools(self) -> Sequence[str]: ...

    def invoke(self, tool_name: str, arguments: Mapping[str, Any]) -> Any: ...


@runtime_checkable
class ToolMiddlewareExtension(Protocol):
    """Protocol for tool middleware plugins."""

    @property
    def middleware_name(self) -> str: ...

    def before_invoke(
        self, tool_name: str, arguments: Mapping[str, Any]
    ) -> Mapping[str, Any]: ...

    def after_invoke(self, tool_name: str, result: Any) -> Any: ...


# ---------------------------------------------------------------------------
# Skill extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class SkillProviderExtension(Protocol):
    """Protocol for skill provider plugins."""

    @property
    def provider_name(self) -> str: ...

    def list_skills(self) -> Sequence[str]: ...

    def get_skill(self, skill_name: str) -> Any: ...


@runtime_checkable
class SkillTemplateExtension(Protocol):
    """Protocol for skill template plugins."""

    @property
    def template_name(self) -> str: ...

    def render(self, context: Mapping[str, Any]) -> str: ...


# ---------------------------------------------------------------------------
# Resource extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class ResourceResolverExtension(Protocol):
    """Protocol for resource resolver plugins."""

    @property
    def resolver_name(self) -> str: ...

    def resolve(self, uri: str) -> Any: ...


@runtime_checkable
class ResourceTypeHandlerExtension(Protocol):
    """Protocol for resource type handler plugins."""

    @property
    def handled_type(self) -> str: ...

    def can_handle(self, resource_type: str) -> bool: ...

    def load(self, uri: str) -> Any: ...


# ---------------------------------------------------------------------------
# A2A extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class A2ATransportExtension(Protocol):
    """Protocol for A2A transport plugins."""

    @property
    def transport_name(self) -> str: ...

    def send(self, destination: str, payload: Any) -> None: ...

    def receive(self) -> Any: ...


@runtime_checkable
class A2AExtensionMethodExtension(Protocol):
    """Protocol for A2A extension method plugins."""

    @property
    def method_name(self) -> str: ...

    def execute(self, params: Mapping[str, Any]) -> Any: ...


# ---------------------------------------------------------------------------
# Event extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class EventHandlerExtension(Protocol):
    """Protocol for event handler plugins."""

    @property
    def handler_name(self) -> str: ...

    def handle(self, event: Any) -> None: ...


@runtime_checkable
class EventFilterExtension(Protocol):
    """Protocol for event filter plugins."""

    @property
    def filter_name(self) -> str: ...

    def should_propagate(self, event: Any) -> bool: ...


# ---------------------------------------------------------------------------
# Config extension protocols (2 extension points)
# ---------------------------------------------------------------------------


@runtime_checkable
class ConfigSourceExtension(Protocol):
    """Protocol for configuration source plugins."""

    @property
    def source_name(self) -> str: ...

    def load(self) -> Mapping[str, Any]: ...


@runtime_checkable
class ConfigValidatorExtension(Protocol):
    """Protocol for configuration validator plugins."""

    @property
    def validator_name(self) -> str: ...

    def validate(self, config: Mapping[str, Any]) -> Sequence[str]: ...


# ---------------------------------------------------------------------------
# Safety extension protocols (1 extension point)
# ---------------------------------------------------------------------------


@runtime_checkable
class SafetyGuardrailExtension(Protocol):
    """Protocol for safety guardrail plugins."""

    @property
    def guardrail_name(self) -> str: ...

    def check(self, action: Any) -> bool: ...

    def explain(self) -> str: ...


# ---------------------------------------------------------------------------
# Re-export mapping for programmatic access
# ---------------------------------------------------------------------------

ALL_EXTENSION_PROTOCOLS: dict[str, type[Any]] = {
    "context.strategy": ContextStrategyExtension,
    "context.pipeline_component.strategy_selector": ContextPipelineComponentExtension,
    "context.pipeline_component.budget_allocator": ContextPipelineComponentExtension,
    "context.pipeline_component.strategy_executor": ContextPipelineComponentExtension,
    "context.pipeline_component.deduplicator": ContextPipelineComponentExtension,
    "context.pipeline_component.depth_resolver": ContextPipelineComponentExtension,
    "context.pipeline_component.scorer": ContextPipelineComponentExtension,
    "context.pipeline_component.packer": ContextPipelineComponentExtension,
    "context.pipeline_component.orderer": ContextPipelineComponentExtension,
    "context.pipeline_component.preamble_generator": ContextPipelineComponentExtension,
    "context.pipeline_component.skeleton_compressor": ContextPipelineComponentExtension,
    "context.storage_backend": ContextStorageBackendExtension,
    "output.renderer": OutputRendererExtension,
    "output.materializer": OutputMaterializerExtension,
    "output.format": OutputFormatExtension,
    "validation.runner": ValidationRunnerExtension,
    "validation.rule_provider": ValidationRuleProviderExtension,
    "tool.provider": ToolProviderExtension,
    "tool.middleware": ToolMiddlewareExtension,
    "skill.provider": SkillProviderExtension,
    "skill.template": SkillTemplateExtension,
    "resource.resolver": ResourceResolverExtension,
    "resource.type_handler": ResourceTypeHandlerExtension,
    "a2a.transport": A2ATransportExtension,
    "a2a.extension_method": A2AExtensionMethodExtension,
    "event.handler": EventHandlerExtension,
    "event.filter": EventFilterExtension,
    "config.source": ConfigSourceExtension,
    "config.validator": ConfigValidatorExtension,
    "safety.guardrail": SafetyGuardrailExtension,
}
