from homie.support.helpers import validate_id


class Node_Base(object):
    def __init__(self, device, id, name, type_, retain=True, qos=1):
        assert validate_id(id), "Node ID {} is not valid".format(id)
        assert device

        self.id = id
        self.name = name
        self.type = type_
        self.device = device

        self.retain = retain
        self.qos = qos

        self.properties = {}

        self.topic = self.device.topic

        self.published = False

    @property
    def topic(self):
        return self._topic

    @topic.setter
    def topic(self, parent_topic):
        self._topic = "/".join([parent_topic, self.id])

    def add_property(self, property_):
        # assert self.properties [property_.id] == None
        assert property_.id not in self.properties

        self.properties[property_.id] = property_

        if self.device.state=="ready":
            self.device.state="init"
            self.publish_properties()
            self.device.state="ready"

    def remove_property(self, property_id):
        property_ = self.properties[property_id]
        del self.properties[property_id]

        if self.device.state=="ready":
#        if self.device.start_time is not None:  # running, publish property changes
            self.device.state="init"
            self.publish_properties()
            property_.publish_attributes(False, 1)
            self.device.state="ready"

    def get_property(self, property_id):
        if property_id in self.properties:
            return self.properties[property_id]
        else:
            return None

    def set_property_value(self, property_id, value):
        self.get_property(property_id).value = value

    def publish(self, topic, payload, retain, qos):
        self.device.publish(topic, payload, retain, qos)

    def property_publisher(
        self, topic, payload, retain, qos
    ):  # properties use this to publish
        if self.published:  # only publish if the node has been published
            self.device.publish(topic, payload, retain, qos)

    def publish_attributes(self, retain=True, qos=1):
        self.publish("/".join((self.topic, "$name")), self.name, retain, qos)
        self.publish("/".join((self.topic, "$type")), self.type, retain, qos)

        self.publish_properties()

    def publish_properties(self, retain=True, qos=1):
        properties = ",".join(self.properties.keys())
        self.publish("/".join((self.topic, "$properties")), properties, retain, qos)

        self.published = True  # node basics published

        for _, property_ in self.properties.items():
            # print ('NODE PUBLISH PROP ',property_.name)
            property_.publish_attributes(retain, qos)

    def get_subscriptions(self):
        subscriptions = {}

        for _, property_ in self.properties.items():
            subscriptions.update(property_.get_subscriptions())

        return subscriptions

