from MQTTObserver import MQTTObserver
from paho.mqtt.client import MQTTMessage, Client
from abc import ABC

class MQTTSubject(ABC):

    def __init__(self):
        """
        Initializes the subject.
        """
        self.observers: dict[str, list[MQTTObserver]] = {}


    def subscribe_observer(self, observer: MQTTObserver, topic: str) -> None:
        """
        Subscribes an observer to a topic.

        Args:
        observer (Observer): The observer to subscribe.
        topic (Topic): The topic to subscribe to.
        """
        if topic not in self.observers.keys():
            self.observers[topic] = []
        if observer not in self.observers[topic]:
            self.observers[topic].append(observer)


    def unsubscribe_observer(self, observer: MQTTObserver, topic: str) -> None:
        """
        Unsubscribes an observer from a topic.

        Args:
        observer (Observer): The observer to unsubscribe.
        topic (Topic): The topic to unsubscribe from.

        Raises:
        ValueError: If the observer is not found in the specified topic.
        """
        if topic in self.observers and observer in self.observers[topic]:
            self.observers[topic].remove(observer)
        else:
            raise ValueError("Observer not found in the specified topic.")


    def notify_observers(self, client : Client, message: MQTTMessage, topic: str) -> None:
        """
        Notifies all observers that are subscribed to a topic.

        Args:
        message (MQTTMessage): The message to send to the observers.
        topic (Topic): The topic to notify the observers of.
        """
        if topic not in self.observers.keys():
            return
    
        for observer in self.observers[topic]:
            observer.update(message)