"""cortex/types/adapters.py — Abstract storage adapter and LLM provider re-export."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any as _Any, List as _List, Optional

from cortex.types.entities import Entity, EntityAlias
from cortex.types.claims import SemanticClaim

# LLMProvider canonical definition lives in cortex.llm.provider (no cortex
# imports there, so re-exporting here is safe and eliminates the dual-ABC).
from cortex.llm.provider import LLMProvider  # noqa: F401


class StorageAdapter(ABC):
    """Minimal storage interface defined in types to avoid circular imports.

    The full StorageAdapter ABC with all CRUD operations lives in
    cortex.storage.adapter. This minimal version defines only the subset
    needed by EntityResolver (M3), which imports both storage types and
    the adapter protocol from cortex.types.

    This pattern avoids the circular import:
        types → adapter → types (would fail)

    See Also:
        cortex.storage.adapter.StorageAdapter for the complete interface.
    """

    @abstractmethod
    async def create_entity(
        self,
        canonical_name: str,
        entity_type: str,
        owner_id: str = "default",
        **kwargs: _Any,
    ) -> "Entity": ...

    @abstractmethod
    async def find_entity_by_alias(
        self, alias: str, owner_id: str = "default"
    ) -> Optional["Entity"]: ...

    @abstractmethod
    async def get_entity_by_id(self, entity_id: str) -> Optional["Entity"]: ...

    @abstractmethod
    async def get_all_entity_aliases(
        self, owner_id: str = "default"
    ) -> _List["EntityAlias"]: ...

    @abstractmethod
    async def add_entity_alias(
        self,
        entity_id: str,
        alias: str,
        alias_type: str = "name",
        **kwargs: _Any,
    ) -> "EntityAlias": ...

    @abstractmethod
    async def merge_entities(self, keep_id: str, merge_id: str) -> "Entity": ...

    @abstractmethod
    async def get_claims_by_entity(
        self,
        entity_id: str,
        owner_id: Optional[str] = None,
    ) -> _List["SemanticClaim"]: ...

    @abstractmethod
    async def update_claim(
        self, claim_id: str, **kwargs: _Any
    ) -> "SemanticClaim": ...
