from __future__ import annotations

from abc import ABC, abstractmethod
from pathlib import Path
from typing import Any, Dict, List, Optional


class BaseStorage(ABC):

    backend_type: str = "base"

    def __init__(self, root: Path) -> None:
        self.root = root
        self._ready = False

    # ------------------------------------------------------------------
    # Lifecycle
    # ------------------------------------------------------------------

    @abstractmethod
    def initialize(self) -> None: ...

    def close(self) -> None:
        pass

    # ------------------------------------------------------------------
    # CRUD primitives
    # ------------------------------------------------------------------

    @abstractmethod
    def put(self, collection: str, key: str, value: Dict[str, Any]) -> None: ...

    @abstractmethod
    def get(self, collection: str, key: str) -> Optional[Dict[str, Any]]: ...

    @abstractmethod
    def delete(self, collection: str, key: str) -> bool: ...

    @abstractmethod
    def list(self, collection: str, prefix: str = "") -> List[Dict[str, Any]]: ...

    @abstractmethod
    def query(self, collection: str, **filters: Any) -> List[Dict[str, Any]]: ...

    # ------------------------------------------------------------------
    # Helpers
    # ------------------------------------------------------------------

    def __repr__(self) -> str:  # pragma: no cover
        return f"<{self.__class__.__name__} root={self.root}>"
