from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.dev.ports.modules.pdc.pdc_io import PDCPortIO
from UniTAP.dev.ports.modules.pdc.pdc_power_sink import PowerSink
from UniTAP.dev.ports.modules.pdc.pdc_contract_control import PowerContractControl340, PowerContractControlBase
from UniTAP.dev.ports.modules.pdc.pdc_power_source import PowerSource
from UniTAP.dev.ports.modules.pdc.pdc_controls import PdcControls340, PdcControls424, PdcControls500
from UniTAP.dev.ports.modules.pdc.pdc_dp_alt_mode import DpAltMode500, DpAltMode340
from UniTAP.dev.ports.modules.pdc.pdc_capabilities import PdcCapabilities, PdcCapabilities340
from UniTAP.dev.ports.modules.pdc.pdc_bus_status import BusElectricalStatus


class PDC:

    """
    Class `PDC` describes capabilities of power delivery controller.
    Contains following field:
    - Power contract control `power_contract_control`, type `PowerContractControlBase`.
    - Power Sink `power_sink`, type `PowerSink`.
    - Power Source `power_source`, type `PowerSource`.
    - DP Alt mode `dp_alt_mode`, type `DpAltMode340`.
    - PDC Capabilities `capabilities`, type `PdcCapabilities`.
    - BUS electrical status `bus_electrical_status`, type `BusElectricalStatus`.
    """

    def __init__(self, port_io: PortIO):
        self._pdc_io = PDCPortIO(port_io)
        self.__power_contract_control = PowerContractControlBase(self._pdc_io)
        self.__power_sink = PowerSink(self._pdc_io)
        self.__power_source = PowerSource(self._pdc_io)
        self.__dpam = DpAltMode340(self._pdc_io)
        self.__caps = PdcCapabilities(self._pdc_io)
        self.__bus_electrical_status = BusElectricalStatus(self._pdc_io)

    @property
    def power_contract_control(self) -> PowerContractControlBase:
        """
        Returns Power contract control.

        Returns:
            object of `PowerContractControlBase` type
        """
        return self.__power_contract_control
    
    @property
    def power_sink(self) -> PowerSink:
        """
        Returns Power Sink.

        Returns:
            object of `PowerSink` type
        """
        return self.__power_sink
    
    @property
    def power_source(self) -> PowerSource:
        """
        Returns Power Source.

        Returns:
            object of `PowerSource` type
        """
        return self.__power_source

    @property
    def dp_alt_mode(self) -> DpAltMode340:
        """
        Returns DP Alt mode.

        Returns:
            object of `DpAltMode340` type
        """
        return self.__dpam

    @property
    def capabilities(self) -> PdcCapabilities:
        """
        Returns PDC capabilities.

        Returns:
            object of `PdcCapabilities` type
        """
        return self.__caps

    @property
    def bus_electrical_status(self) -> BusElectricalStatus:
        """
        Returns BUS electrical status.

        Returns:
            object of `BusElectricalStatus` type
        """
        return self.__bus_electrical_status

    def __str__(self) -> str:
        return (f"DP Alt Mode\n{self.dp_alt_mode}\n"
                f"{self.power_sink}\n"
                f"{self.power_source}\n"
                f"{self.power_contract_control}\n"
                f"{self.capabilities.status}\n"
                f"{self.bus_electrical_status}\n")


class PDC340(PDC):

    """
    Class `PDC340` inherited from class `PDC`.
    Class `PDC340` allows working with overriding PDc controls and power contract control.
    Also has all the `PDC` functionality.
    - Power Contract control `power_contract_control`, type `PowerContractControl340`.
    - PDC Controls `controls`, type `PdcControls340`.
    """

    def __init__(self, port_io: PortIO):
        super().__init__(port_io)
        self.__power_contract_control = PowerContractControl340(self._pdc_io)
        self.__controls = PdcControls340(self._pdc_io)
        self.__caps = PdcCapabilities340(self._pdc_io)

    @property
    def capabilities(self) -> PdcCapabilities340:
        """
        Returns PDC capabilities.

        Returns:
            object of `PdcCapabilities340` type
        """
        return self.__caps

    @property
    def power_contract_control(self) -> PowerContractControl340:
        """
        Returns Power contract control.

        Returns:
            object of `PowerContractControl340` type
        """
        return self.__power_contract_control

    @property
    def controls(self) -> PdcControls340:
        """
        Returns PDC Controls.

        Returns:
            object of `PdcControls340` type
        """
        return self.__controls

    def __str__(self) -> str:
        return (f"DP Alt Mode\n{self.dp_alt_mode}\n"
                f"{self.power_sink}\n"
                f"{self.power_source}\n"
                f"{self.power_contract_control}\n"
                f"{self.capabilities.status}"
                f"{self.bus_electrical_status}\n")


class PDC424(PDC):

    """
    Class `PDC424` inherited from class `PDC`.
    Class `PDC424` allows working with overriding controls.
    Also has all the `PDC` functionality.
    - PDC Controls `controls`, type `PdcControls340`.
    """

    def __init__(self, port_io: PortIO):
        super().__init__(port_io)
        self.__controls = PdcControls424(self._pdc_io)

    @property
    def controls(self) -> PdcControls424:
        """
        Returns PDC Controls.

        Returns:
            object of `PdcControls424` type
        """
        return self.__controls


class PDC500(PDC):

    """
    Class `PDC500` inherited from class `PDC`.
    Class `PDC500` allows working with overriding controls and DP Alt mode.
    Also has all the `PDC` functionality.
    - PDC Controls `controls`, type `PdcControls500`.
    - DP Alt mode `dp_alt_mode`, type `DpAltMode500`.
    """

    def __init__(self, port_io: PortIO):
        super().__init__(port_io)
        self.__controls = PdcControls500(self._pdc_io)
        self.__dpam = DpAltMode500(self._pdc_io)

    @property
    def controls(self) -> PdcControls500:
        """
        Returns PDC Controls.

        Returns:
            object of `PdcControls500` type
        """
        return self.__controls

    @property
    def dp_alt_mode(self) -> DpAltMode500:
        """
        Returns DP Alt mode.

        Returns:
            object of `DpAltMode500` type
        """
        return self.__dpam
