# Source code for kasa.interfaces.lightpreset

    """Interact with TPLink Light Presets.

    >>> from kasa import Discover, Module, LightState
    >>>
    >>> dev = await Discover.discover_single(
    >>>     "127.0.0.3",
    >>>     username="user@example.com",
    >>>     password="great_password"
    >>> )
    >>> await dev.update()
    >>> print(dev.alias)
    Living Room Bulb

    Light presets are accessed via the LightPreset module. To list available presets

    >>> light_preset = dev.modules[Module.LightPreset]
    >>> light_preset.preset_list
    ['Not set', 'Light preset 1', 'Light preset 2', 'Light preset 3',\
     'Light preset 4', 'Light preset 5', 'Light preset 6', 'Light preset 7']

    To view the currently selected preset:

    >>> light_preset.preset
    Not set

    To view the actual light state for the presets:

    >>> len(light_preset.preset_states_list)
    7

    >>> light_preset.preset_states_list[0]
    LightState(light_on=None, brightness=50, hue=0,\
     saturation=100, color_temp=2700, transition=None)

    To set a preset as active:

    >>> dev.modules[Module.Light].state  # This is only needed to show the example working
    LightState(light_on=True, brightness=100, hue=0,\
     saturation=100, color_temp=2700, transition=None)
    >>> await light_preset.set_preset("Light preset 1")
    >>> await dev.update()
    >>> light_preset.preset
    Light preset 1
    >>> dev.modules[Module.Light].state  # This is only needed to show the example working
    LightState(light_on=True, brightness=50, hue=0,\
     saturation=100, color_temp=2700, transition=None)

    You can save a new preset state if the device supports it:

    >>> if light_preset.has_save_preset:
    >>>     new_preset_state = LightState(light_on=True, brightness=75, hue=0,\
     saturation=100, color_temp=2700, transition=None)
    >>>     await light_preset.save_preset("Light preset 1", new_preset_state)
    >>> await dev.update()
    >>> light_preset.preset  # Saving updates the preset state for the preset, it does not \
    set the preset
    Not set
    >>> light_preset.preset_states_list[0]
    LightState(light_on=None, brightness=75, hue=0,\
     saturation=100, color_temp=2700, transition=None)

    If you manually set the light state to a preset state it will show that preset as \
        active:

    >>> await dev.modules[Module.Light].set_brightness(75)
    >>> await dev.update()
    >>> light_preset.preset
    Light preset 1
    """

    from __future__ import annotations

    from abc import abstractmethod
    from collections.abc import Sequence

    from ..feature import Feature
    from ..module import Module
    from .light import LightState

    class LightPreset(Module):
        """Base interface for light preset module."""

        PRESET_NOT_SET = "Not set"

        def _initialize_features(self) -> None:
            """Initialize features."""
            device = self._device
            self._add_feature(
                Feature(
                    device,
                    id="light_preset",
                    name="Light preset",
                    container=self,
                    attribute_getter="preset",
                    attribute_setter="set_preset",
                    category=Feature.Category.Config,
                    type=Feature.Type.Choice,
                    choices_getter="preset_list",
                )
            )

        @property
        @abstractmethod
        def preset_list(self) -> list[str]:
            """Return list of preset names.

            Example:
                ['Off', 'Preset 1', 'Preset 2', ...]
            """

        @property
        @abstractmethod
        def preset_states_list(self) -> Sequence[LightState]:
            """Return list of preset states.

            Example:
                ['Off', 'Preset 1', 'Preset 2', ...]
            """

        @property
        @abstractmethod
        def preset(self) -> str:
            """Return current preset name."""

        @abstractmethod
        async def set_preset(
            self,
            preset_name: str,
        ) -> dict:
            """Set a light preset for the device."""

        @abstractmethod
        async def save_preset(
            self,
            preset_name: str,
            preset_info: LightState,
        ) -> dict:
            """Update the preset with *preset_name* with the new *preset_info*."""

        @property
        @abstractmethod
        def has_save_preset(self) -> bool:
            """Return True if the device supports updating presets."""