"""Component interface definition - equivalent to C++ IComponent."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Protocol

if TYPE_CHECKING:
    from .imainctrl import IMainCtrl


class IComponent(ABC):
    """Abstract base class for all LSCSIM components.

    This interface defines the contract that all components must implement,
    equivalent to the C++ IComponent interface.
    """

    @abstractmethod
    def get_id(self) -> str:
        """Get component unique identifier.

        Returns
        -------
            str: Unique component ID string
        """

    @abstractmethod
    def set_main_ctrl(self, main_ctrl: IMainCtrl) -> None:
        """Set the main controller reference.

        Args:
            main_ctrl: Reference to the main controller
        """

    @abstractmethod
    def init(self) -> None:
        """Initialize the component.

        Called after component registration to perform setup operations.
        """

    @abstractmethod
    def release(self) -> None:
        """Release component resources.

        Called before component destruction to cleanup resources.
        """

    @abstractmethod
    def get_interface_count(self) -> int:
        """Get number of supported interfaces.

        Returns
        -------
            int: Number of interfaces this component provides
        """

    @abstractmethod
    def get_interface_id(self, index: int) -> str:
        """Get interface ID by index.

        Args:
            index: Interface index

        Returns
        -------
            str: Interface identifier
        """

    @abstractmethod
    def get_interface_ptr(self, interface_id: str) -> object | None:
        """Get interface pointer by ID.

        Args:
            interface_id: Interface identifier

        Returns
        -------
            object | None: Interface implementation or None if not supported
        """


# Protocol version for type checking
class ComponentProtocol(Protocol):
    """Protocol for component type checking."""

    def get_id(self) -> str:
        """Get component unique identifier.

        Returns
        -------
            str: Unique component ID string
        """

    def set_main_ctrl(self, main_ctrl: IMainCtrl) -> None:
        """Set the main controller reference.

        Args:
            main_ctrl: Reference to the main controller
        """

    def init(self) -> None:
        """Initialize the component.

        Called after component registration to perform setup operations.
        """

    def release(self) -> None:
        """Release component resources.

        Called before component destruction to cleanup resources.
        """

    def get_interface_count(self) -> int:
        """Get number of supported interfaces.

        Returns
        -------
            int: Number of interfaces this component provides
        """

    def get_interface_id(self, index: int) -> str:
        """Get interface ID by index.

        Args:
            index: Interface index

        Returns
        -------
            str: Interface identifier
        """

    def get_interface_ptr(self, interface_id: str) -> object | None:
        """Get interface pointer by ID.

        Args:
            interface_id: Interface identifier

        Returns
        -------
            object | None: Interface implementation or None if not supported
        """
