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

CURRENT_POINT_TOPIC         = "CURRENT_POINT"
CURRENT_POINT_TOPIC_PATH    = "htc_ipc/+/export_symbols/" + CURRENT_POINT_TOPIC

class currentStopMonitoringService(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.topic = "current_stop/stop"
        else:
            self.topic = customerID + "/" + VIN + "/hanover/current_stop/stop"

        self.mqttService = mqtt.mqttService("mqtt-monitoring-current-stop-service",
                                            broker    = broker,
                                            port      = port,
                                            user_name = user_name,
                                            password  = password,
                                            callback = self.topicUpdated,
                                            service = self)
        
        self.topic_dictionary = {
            "atDateTime":           "",
            "stopCode":             "",
            "stopNames":            {
                "langCode":             "en",
                "text":                 ""
            },
            "sequenceNumber":           0,
            "location":             {
                "latitude":             {
                    "degree":               0.0,
                    "direction":            "E"
                },
                "longitude":            {
                    "degree":               0.0,
                    "direction":            "N"
                }
            },
            "additionalAttributes": {}
        }

        self.current_point = ""
        self.current_point_id = ""
        self.current_point_name = ""
        self.current_point_lat = 0.0
        self.current_point_long = 0.0

        self.mqttService.subscribe(CURRENT_POINT_TOPIC_PATH)

        self.publish()

    def topicUpdated(mqtt, self, topic, payload):
        if topic.endswith(CURRENT_POINT_TOPIC):
            current_point = payload
            self.currentPointUpdated(current_point)

    def currentPointUpdated(self, current_point):
        if self.current_point != current_point:

            self.current_point = current_point
            logger.debug(f"Got new current point, code: {self.current_point}")

            db = htcdb.databaseAccess()
            self.current_point_id = db.getAttribute(self.current_point, "PointIdentifier")
            logger.debug(f"current_point_id: {self.current_point_id}")

            self.current_point_name = db.getAttribute(self.current_point, "Name")
            logger.debug(f"current_point_name: {self.current_point_name}")

            self.current_point_lat = float(db.getAttribute(self.current_point, "Latitude"))
            logger.debug(f"current_point_lat: {self.current_point_lat}")

            self.current_point_long = float(db.getAttribute(self.current_point, "Longitude"))
            logger.debug(f"current_point_long: {self.current_point_long}")

            self.publish()


    def updateDictionary(self):
        self.topic_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        self.topic_dictionary["stopCode"] = self.current_point_id

        stop_names_dict = {
            "langCode":             "en",
            "text":                 self.current_point_name
        }

        self.topic_dictionary["stopNames"] = stop_names_dict
        self.topic_dictionary["sequenceNumber"] = 0

        lat = self.current_point_lat
        lat_dir = "E"
        long = self.current_point_long
        long_dir = "N"

        # check for negative values and convert to absolute with directions
        if lat < 0:
            lat = abs(lat)
            lat_dir = "W"
        if long < 0:
            long = abs(long)
            long_dir = "S"

        lat_dict = {
            "degree": lat,
            "direction": lat_dir
        }

        long_dict = {
            "degree": long,
            "direction": long_dir
        }

        location_dict = {
            "latitude": lat_dict,
            "longitude": long_dict
        }

        self.topic_dictionary["location"] = location_dict


    def publish(self):
        self.updateDictionary()

        logger.debug(f"publish - {self.topic}\n{self.topic_dictionary}\n")
        self.mqttService.publish(self.topic, self.topic_dictionary)

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

    #use local broker to forward topics
    currentStopMonService = currentStopMonitoringService()

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

    while 1:
        currentStopMonService.publish()
        time.sleep(5)
