from abc import ABC, abstractmethod
from typing import Generic, TypeVar

from bclearer_core.configurations.datastructure.logging_inspection_level_b_enums import (
    LoggingInspectionLevelBEnums,
)
from bclearer_core.objects.b_units.b_units import BUnits
from bclearer_core.objects.universes.universes import Universes
from bclearer_orchestration_services.reporting_service.reporters.inspection_message_logger import (
    log_inspection_message,
)

TUniverse = TypeVar("TUniverse", bound=Universes)


class BUnitsWithObjectPassingAndReturning(
    BUnits,
    Generic[TUniverse],
    ABC,
):
    """
    Generic B-Unit that accepts and operates on a Universe object.

    This pattern enables pipeline steps to:
    - Receive a Universe containing pipeline state and data
    - Access registries and configuration through the Universe
    - Mutate the Universe by adding/modifying data in registers
    - Pass the modified Universe to the next B-Unit
    """

    def __init__(
        self,
        input_object: TUniverse,
    ) -> None:
        super().__init__()

        self.input_object: TUniverse = input_object

    def run(self) -> None:
        log_inspection_message(
            message=f"Running B-Unit: {self.__class__.__name__}",
            logging_inspection_level_b_enum=LoggingInspectionLevelBEnums.INFO,
        )

        self.b_unit_process_function()

    def b_unit_process_function(
        self,
    ) -> ():
        self._b_unit_process_function()

    @abstractmethod
    def _b_unit_process_function(
        self,
    ) -> None:
        pass
