#!/usr/bin/env python3
import time
import mqtt_service as mqtt
import datetime
import traceback
import logging
import signal
logger = logging.getLogger(__name__)

class destinationInfoMonitoringService(object):
    def __init__(self, broker            = "127.0.0.1",
                       port              = 1883,
                       user_name         = "",
                       password          = "",
                       customerID        = "",
                       VIN               = "",
                ):

        def inc_level(sig, frame):
            level = logger.getEffectiveLevel()
            if level == logging.CRITICAL:
                logger.setLevel(logging.ERROR)
            elif level == logging.ERROR:
                logger.setLevel(logging.WARNING)
            elif level == logging.WARNING:
                logger.setLevel(logging.INFO)
            elif level == logging.INFO:
                logger.setLevel(logging.DEBUG)
            print(f"Set logging to {logging.getLevelName(logger.getEffectiveLevel())}")

        def dec_level(sig, frame):
            level = logger.getEffectiveLevel()
            if level == logging.NOTSET:
                logger.setLevel(logging.DEBUG)
            elif level == logging.DEBUG:
                logger.setLevel(logging.INFO)
            elif level == logging.INFO:
                logger.setLevel(logging.WARNING)
            elif level == logging.WARNING:
                logger.setLevel(logging.ERROR)
            elif level == logging.ERROR:
                logger.setLevel(logging.CRITICAL)
            print(f"Set logging to {logging.getLevelName(logger.getEffectiveLevel())}")

        signal.signal(signal.SIGUSR2, inc_level)
        signal.signal(signal.SIGUSR1, dec_level)

        if customerID == "":
            self.topicDestCode = "destination_info/dest_code"
            self.topicRouteCode = "destination_info/route_code"
            self.topicDriverMessage = "destination_info/driver_message"
        else:
            self.topicDestCode = customerID + "/" + VIN + "/hanover/destination_info/dest_code"
            self.topicRouteCode = customerID + "/" + VIN + "/hanover/destination_info/route_code"
            self.topicDriverMessage = customerID + "/" + VIN + "/hanover/destination_info/driver_message"

        self.mqttService = mqtt.mqttService("mqtt-monitoring-destination-info-service",
                                            broker    = broker,
                                            port      = port,
                                            user_name = user_name,
                                            password  = password)
        
        self.dest_code_dictionary = {
            "atDateTime":           "",
            "destCode":             ""
        }

        self.route_code_dictionary = {
            "atDateTime":           "",
            "routeCode":            ""
        }

        self.driver_message_dictionary = {
            "atDateTime":           "",
            "driverMessage":        [ {"text": ""}, {"text": ""} ]
        }

        self.dest_code = None
        self.route_code = None
        self.driver_message = []

    def setDestCode(self, dest_code):
        if dest_code != self.dest_code:
            self.dest_code = dest_code
            self.dest_code_dictionary["destCode"] = self.dest_code
            return True
        else:
            return False


    def setRouteCode(self, route_code):
        if route_code != self.route_code:
            self.route_code = route_code
            self.route_code_dictionary["routeCode"] = self.route_code
            return True
        else:
            return False

    def setDriverMessage(self, driver_message):
        if driver_message != self.driver_message:
            self.driver_message = driver_message

            # create the list of text="" pairs
            dm_list = []
            for message in driver_message:
                dm_dict = {}
                dm_dict["text"] = message
                dm_list.append(dm_dict)

            self.driver_message_dictionary["driverMessage"] = dm_list

            return True
        else:
            return False

    def publishDestCode(self):
        self.dest_code_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        logger.debug(f"publish - {self.topicDestCode}\n{self.dest_code_dictionary}\n")
        self.mqttService.publish(self.topicDestCode, self.dest_code_dictionary)

    def publishRouteCode(self):
        self.route_code_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        logger.debug(f"publish - {self.topicRouteCode}\n{self.route_code_dictionary}\n")
        self.mqttService.publish(self.topicRouteCode, self.route_code_dictionary)

    def publishDriverMessage(self):
        self.driver_message_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        logger.debug(f"publish - {self.topicDriverMessage}\n{self.driver_message_dictionary}\n")
        self.mqttService.publish(self.topicDriverMessage, self.driver_message_dictionary)

if __name__ == "__main__":
    logger.info("Destination Info Monitoring Service running in foreground")

    #use local broker to forward topics
    diMonService = destinationInfoMonitoringService()

    diMonService.setDestCode("100")
    diMonService.setRouteCode("300")
    diMonService.setDriverMessage(["text1", "text2"])

    #send topics direct to cloud
    #diMonService = destinationInfoMonitoringService(broker           = "mqtt.ver.hanover.cloud",
    #                                               port              = 2023,
    #                                               user_name         = "1031_300",
    #                                               password          = "z3Qs38jn",
    #                                               customerID        = "1031",
    #                                               VIN               = "0")

    while 1:
        diMonService.publishDestCode()
        diMonService.publishRouteCode()
        diMonService.publishDriverMessage()
        time.sleep(5)
