"""Base class for EZ-Input backend plugins."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Dict

try:
    from fastapi import FastAPI
except ImportError:  # pragma: no cover - allows importing without FastAPI installed
    FastAPI = Any  # type: ignore[misc,assignment]


class Plugin(ABC):
    """Abstract base class that every EZ-Input backend plugin must implement.

    A plugin is a self-contained unit that can register FastAPI routes, expose
    health metadata, and declare dependencies. The :class:`PluginRegistry`
    discovers subclasses of this class at runtime.
    """

    name: str = ""
    version: str = "0.0.0"
    description: str = ""
    dependencies: list[str] = []

    def __init__(self) -> None:
        if not self.name:
            self.name = self.__class__.__name__
        self.context: Dict[str, Any] = {}

    @abstractmethod
    def register(self, app: FastAPI) -> None:
        """Register this plugin's routes and handlers on the provided FastAPI app.

        Args:
            app: The FastAPI application to extend.
        """

    def activate(self) -> None:
        """Optional lifecycle hook called after all plugins are registered.

        Override to start background tasks, open connections, etc.
        """

    def bind(self, context: Dict[str, Any]) -> "Plugin":
        """Bind a shared context dict to this plugin and return self."""
        self.context = context
        return self

    def health(self) -> Dict[str, Any]:
        """Return plugin-specific health/status metadata.

        Override to include runtime state (database connectivity, queues, etc.).
        """
        return {
            "name": self.name,
            "version": self.version,
            "status": "ok",
        }

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__} name={self.name!r} version={self.version}>"


# Re-export registry so consumers can import the full plugin API from one module.
from registry import PluginRegistry  # noqa: E402
