"""
Caprail Service Provider base class.

Service providers are the central place for bootstrapping framework
and application services. Each provider has register() and boot()
lifecycle hooks, mirroring Laravel's provider system.
"""
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from caprail.application import Application


class ServiceProvider:
    """
    Base class for all Caprail service providers.

    Subclass this and implement ``register()`` and/or ``boot()`` to
    wire up bindings and perform bootstrap logic.
    """

    #: Set to True if the provider should be deferred (lazy-loaded).
    defer: bool = False

    #: List of abstract names this provider provides (used when defer=True).
    provides: list[str] = []

    def __init__(self, app: "Application") -> None:
        self.app = app

    def register(self) -> None:
        """
        Register bindings in the container.

        This is always called before ``boot()``.  Do not use other
        services here — they may not be registered yet.
        """

    def boot(self) -> None:
        """
        Bootstrap any application services.

        Called after all providers have been registered.
        """

    # ------------------------------------------------------------------
    # Convenience helpers
    # ------------------------------------------------------------------

    def bind(self, abstract: str | type, concrete=None, shared: bool = False) -> None:
        self.app.bind(abstract, concrete, shared)

    def singleton(self, abstract: str | type, concrete=None) -> None:
        self.app.singleton(abstract, concrete)

    def instance(self, abstract: str | type, value) -> None:
        self.app.instance(abstract, value)
