"""
Protocol definitions for pycharter-wiki interfaces.

These protocols define the expected interfaces for extensible components,
enabling type checking and clear contracts for custom implementations.
"""

from __future__ import annotations

from typing import Any, Protocol, runtime_checkable

# =============================================================================
# Ontology Store Protocol
# =============================================================================


@runtime_checkable
class OntologyStore(Protocol):
    """
    Protocol for ontology storage implementations.

    All ontology stores must implement this interface for storing
    and retrieving ontology artifacts.

    Example implementation:
        >>> class MyOntologyStore:
        ...     def get_ontology(self, contract_id: str, version: str = None) -> dict | None:
        ...         return {"version": "1.0.0", "fields": {...}}
    """

    def get_ontology(
        self, contract_id: str, version: str | None = None
    ) -> dict[str, Any]:
        """Get an ontology by contract ID and optional version."""
        ...

    def store_ontology(
        self,
        contract_id: str,
        ontology: dict[str, Any],
        version: str | None = None,
        author: str | None = None,
    ) -> str:
        """Store an ontology and return its version ID."""
        ...

    def list_ontologies(self) -> list[dict[str, Any]]:
        """List all available ontologies."""
        ...

    def export_ontology_jsonld(
        self,
        contract_id: str,
        version: str | None = None,
    ) -> dict[str, Any] | None:
        """Export an ontology as a JSON-LD document (optional)."""
        return None

    def validate_ontology_shacl(
        self,
        contract_id: str,
        version: str | None = None,
    ) -> Any:
        """Run SHACL validation on an ontology (optional). Returns ShaclReport or None."""
        return None


# =============================================================================
# Version Store Protocol
# =============================================================================


@runtime_checkable
class VersionStore(Protocol):
    """
    Protocol for version history storage.

    Manages the event-sourced version history of ontology artifacts.
    """

    def get_version(self, version_id: str) -> dict[str, Any]:
        """Get a specific version by ID."""
        ...

    def get_latest(self, contract_id: str, branch: str | None = None) -> dict[str, Any]:
        """Get the latest version for a contract, optionally on a specific branch."""
        ...

    def create_version(
        self,
        contract_id: str,
        content: dict[str, Any],
        message: str,
        author: str,
        parent_id: str | None = None,
        branch: str | None = None,
    ) -> str:
        """Create a new version and return its ID."""
        ...

    def get_history(
        self, contract_id: str, branch: str | None = None, limit: int = 50
    ) -> list[dict[str, Any]]:
        """Get version history for a contract."""
        ...


# =============================================================================
# Graph Traverser Protocol
# =============================================================================


@runtime_checkable
class GraphTraverser(Protocol):
    """
    Protocol for knowledge graph traversal.

    Provides methods for navigating the concept hierarchy and
    field relationships in the knowledge graph.
    """

    def get_ancestors(self, concept_id: str) -> list[dict[str, Any]]:
        """Get all ancestor concepts (parent, grandparent, etc.)."""
        ...

    def get_descendants(self, concept_id: str) -> list[dict[str, Any]]:
        """Get all descendant concepts (children, grandchildren, etc.)."""
        ...

    def get_related_fields(self, concept_id: str) -> list[dict[str, Any]]:
        """Get all fields associated with a concept."""
        ...

    def get_concept_tree(self) -> dict[str, Any]:
        """Get the full concept hierarchy as a tree."""
        ...


# =============================================================================
# Conflict Resolver Protocol
# =============================================================================


@runtime_checkable
class ConflictResolver(Protocol):
    """
    Protocol for merge conflict resolution.

    Provides strategies for resolving conflicts when merging
    ontology changes from different branches.
    """

    def resolve(
        self,
        base: dict[str, Any],
        ours: dict[str, Any],
        theirs: dict[str, Any],
        field_path: str,
    ) -> dict[str, Any]:
        """
        Resolve a conflict for a specific field.

        Args:
            base: The common ancestor value
            ours: Our branch's value
            theirs: Their branch's value
            field_path: Path to the conflicting field

        Returns:
            The resolved value
        """
        ...

    def can_auto_resolve(
        self,
        base: dict[str, Any],
        ours: dict[str, Any],
        theirs: dict[str, Any],
        field_path: str,
    ) -> bool:
        """Check if a conflict can be automatically resolved."""
        ...
