from enum import Enum
from typing import TypedDict, Protocol, runtime_checkable, Dict


class PropertyName(str, Enum):
    """
    Enumeration of property names tracked in the inventory.

    :cvar CPU_SERIAL_NUMBER: Serial number of the CPU.
    :cvar UBOOT_VERSION: U-Boot version.
    :cvar ECP_VERSION: ECP version.
    :cvar IMAGE_VERSION: Image version.
    :cvar RESCUE_OS_VERSION: Rescue OS version.
    """
    CPU_SERIAL_NUMBER = "cpuSerialNumber"
    UBOOT_VERSION = "uBootVersion"
    ECP_VERSION = "ecpVersion"
    IMAGE_VERSION = "imageVersion"
    RESCUE_OS_VERSION = "rescueOSVersion"

class Property(TypedDict, total=False):
    """
    Represents a property with current and previous values and timestamps.

    :param value: The current value.
    :type value: str
    :param oldValue: The previous value (optional).
    :type oldValue: str
    :param registerDate: The date when the current value was registered (optional).
    :type registerDate: str
    :param oldRegisterDate: The date when the old value was registered (optional).
    :type oldRegisterDate: str
    """
    value: str
    oldValue: str
    registerDate: str
    oldRegisterDate: str

Properties = Dict[PropertyName, Property]

class Inventory(TypedDict):
    """
    Represents an inventory containing a dictionary of properties.

    :param properties: Dictionary mapping property names to their values.
    :type properties: Properties
    """
    properties: Properties

@runtime_checkable
class GeneratorInterface(Protocol):
    """
    Protocol for generators that produce inventory property values.

    Requires a property name and two asynchronous methods: one for generating
    the property value and one for optionally performing a call-to-action.
    """

    @property
    def name(self) -> PropertyName:
        """
        The name of the property generated.

        :return: Property name.
        :rtype: PropertyName
        """
        ...

    async def generate(self, base: Property) -> Property:
        """
        Generate a new value for the property.

        :param base: The base property from which to generate a new value.
        :type base: Property
        :return: The updated property with potentially new values.
        :rtype: Property
        """
        ...

    async def runCallToActions(self) -> None:
        """
        Optional call-to-action method.

        Used to perform side effects or trigger external processes as needed.
        """
        ...