"""
interface.py
------------
Abstract interfaces for pluggable storage backends.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Tuple, Sequence
import numpy as np


class VectorBackend(ABC):
    """Abstract interface for vector storage backends."""

    @abstractmethod
    def add(
        self,
        ids: Sequence[str],
        embeddings: np.ndarray,
        metadata: Optional[List[Dict[str, Any]]] = None,
    ) -> None:
        """Add vectors to the index."""
        pass

    @abstractmethod
    def search(
        self,
        query_embedding: np.ndarray,
        k: int = 10,
        filter: Optional[Dict[str, Any]] = None,
    ) -> List[Tuple[str, float, Dict[str, Any]]]:
        """
        Search for similar vectors.

        Returns:
            List of (id, score, metadata) tuples.
        """
        pass

    @abstractmethod
    def get(
        self, ids: Sequence[str]
    ) -> List[Optional[Tuple[str, np.ndarray, Dict[str, Any]]]]:
        """
        Get vectors by ID.
        Returns: List of (id, embedding, metadata) or None if not found.
        """
        pass

    @abstractmethod
    def delete(self, ids: Sequence[str]) -> None:
        """Delete vectors by ID."""
        pass

    @abstractmethod
    def count(self) -> int:
        """Return total number of vectors."""
        pass

    @abstractmethod
    def clear(self) -> None:
        """Clear all data."""
        pass


class GraphBackend(ABC):
    """Abstract interface for graph storage backends."""

    @abstractmethod
    def add_triples(self, triples: List[Tuple[str, str, str, Dict[str, Any]]]) -> None:
        """
        Add triples (head, relation, tail, properties) to the graph.
        """
        pass

    @abstractmethod
    def search_triples(
        self,
        head: Optional[str] = None,
        relation: Optional[str] = None,
        tail: Optional[str] = None,
    ) -> List[Tuple[str, str, str, Dict[str, Any]]]:
        """Search for triples matching the pattern."""
        pass

    @abstractmethod
    def get_neighbors(
        self, node: str, depth: int = 1
    ) -> List[Tuple[str, str, str, Dict[str, Any]]]:
        """Get neighbors of a node up to a certain depth."""
        pass

    @abstractmethod
    def delete_triples(self, triples: List[Tuple[str, str, str]]) -> None:
        """Delete specific triples."""
        pass

    @abstractmethod
    def clear(self) -> None:
        """Clear all data."""
        pass
