"""
Vector Store base types and interfaces.

Contains abstract interface, data classes, and exceptions for vector stores.
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass


def is_glob_pattern(path: str) -> bool:
    """
    Check if a path contains glob wildcard characters.

    Args:
        path: File path to check

    Returns:
        True if path contains *, ?, or [ characters (glob wildcards)
    """
    return any(c in path for c in "*?[")


class VectorStoreError(Exception):
    """Base exception for vector store errors."""

    pass


@dataclass
class SearchResult:
    """Search result from vector store."""

    chunk_id: str
    file_path: str
    start_line: int
    end_line: int
    content: str
    score: float
    metadata: dict


class VectorStoreInterface(ABC):
    """Abstract interface for vector stores."""

    @abstractmethod
    async def upsert(
        self,
        chunk_id: str,
        vector: list[float],
        payload: dict,
        collection_name: str | None = None,
    ) -> None:
        """Insert or update a vector with its payload."""
        pass

    @abstractmethod
    async def delete_by_file(self, file_path: str, collection_name: str | None = None) -> int:
        """Delete all vectors for a file, return count deleted."""
        pass

    @abstractmethod
    async def search(
        self,
        query_vector: list[float],
        limit: int = 10,
        file_filter: str | None = None,
        collection_name: str | None = None,
        artifact_types: list[str] | None = None,
    ) -> list[SearchResult]:
        """
        Search for similar vectors.

        Args:
            query_vector: Query embedding vector
            limit: Maximum results to return
            file_filter: Optional glob pattern for file paths
            collection_name: Optional collection to search
            artifact_types: Optional list of artifact types to filter by

        Returns:
            List of SearchResult sorted by score descending
        """
        pass

    @abstractmethod
    async def get_stats(self, collection_name: str | None = None) -> dict:
        """Get storage statistics."""
        pass

    @abstractmethod
    async def get_by_id(self, chunk_id: str) -> SearchResult | None:
        """Get a specific chunk by ID."""
        pass

    @abstractmethod
    async def get_all_file_paths(self, collection_name: str | None = None) -> list[str]:
        """Get all unique file paths in the store."""
        pass

    async def reset(self) -> None:
        """Reset/clear the vector store (optional)."""
        pass

    @abstractmethod
    async def delete_collection(self, collection_name: str) -> bool:
        """Delete a collection entirely."""
        pass
