# SPDX-FileCopyrightText: © 2023 Christian BUHTZ <c.buhtz@posteo.jp>
#
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the program "Hyperorg" which is released under GNU
# General Public License v3 (GPLv3).
# See folder LICENSES or go to <https://www.gnu.org/licenses/#GPL>.
"""Observer-Pattern like implementation.

Regarding that pattern an object of type `Event` is the "Subject" and every
object calling `Event.register()` is an "Observer".

See https://stackoverflow.com/a/48339861/4865723
"""
from contextlib import contextmanager


class Event:
    """Instance of this event (aka subject) can notify its observers."""

    def __init__(self):
        self._callbacks = []

    def notify(self, *args, **kwargs):
        """Notify registered observers.

        The args, and kwargs are given to the observers.
        """

        for callback in self._callbacks:
            callback(*args, **kwargs)

    def register(self, callback):
        """Register an observer (callback function).
        """

        if callback not in self._callbacks:
            self._callbacks.append(callback)

        return callback

    def deregister(self, callback):
        """Deregister / remove an observer (callback function).
        """
        self._callbacks.remove(callback)

    @contextmanager
    def register_temp(self, callback):
        """A context manager function to temporaryly register an observer.

        See `register()` for details.
        """

        self.register(callback)

        yield

        self.deregister(callback)

    # @contextmanager
    # def keep_silent(self):
    #     """A context manager function to suppress notification's of the
    #        observers."""
    #     try:
    #         self._silent_callbacks = self._callbacks
    #         self._callbacks = []
    #         yield
    #     finally:
    #         self._callbacks = self._silent_callbacks
