"""Abstract search backend interface."""

from __future__ import annotations

from abc import ABC, abstractmethod

from search.models import (
    IndexConfig,
    SearchDocument,
    SearchQuery,
    SearchResponse,
)


class SearchBackend(ABC):
    """Base class for all search backends.

    Every backend must implement index, search, delete, and index management
    operations. ``bulk_index`` has a default sequential implementation that
    backends may override for better throughput.
    """

    @abstractmethod
    async def index(self, document: SearchDocument) -> None:
        """Index a single document (upsert semantics)."""

    @abstractmethod
    async def search(self, index_name: str, query: SearchQuery) -> SearchResponse:
        """Execute a search query against *index_name*."""

    @abstractmethod
    async def delete(self, index_name: str, document_id: str) -> bool:
        """Delete a document by id. Return ``True`` if it existed."""

    @abstractmethod
    async def create_index(self, config: IndexConfig) -> None:
        """Create or update an index with the given configuration."""

    @abstractmethod
    async def delete_index(self, index_name: str) -> None:
        """Delete an entire index and all its documents."""

    async def bulk_index(self, documents: list[SearchDocument]) -> int:
        """Index multiple documents. Return count of documents indexed.

        Default implementation indexes sequentially. Backends should override
        for batch efficiency.
        """
        for doc in documents:
            await self.index(doc)
        return len(documents)

    async def close(self) -> None:
        """Release any resources held by the backend."""
