from abc import ABC, abstractmethod
from typing import Callable


class AlarmStyle(ABC):
    """A pluggable alarm behaviour.

    A style decides *when* the alarm stops and what the LED does while it
    rings. It never touches hardware directly: ``set_led`` is injected by the
    runner, so styles stay import-safe in the API process (no GPIO/pygame).

    Lifecycle: construct once with ``set_led``, then call ``update`` every
    tick. Return ``False`` from ``update`` to stop the alarm.
    """

    def __init__(self, set_led: Callable[[bool], None]):
        self.set_led = set_led

    @abstractmethod
    def update(self, now: float, is_pressed: bool) -> bool:
        """Advance the style by one tick.

        Args:
            now: current time (``time.time()`` from the runner).
            is_pressed: whether the button is currently held down.

        Returns:
            True to keep ringing, False to stop.
        """
