"""
Name: status_handler
Title: 
Author: Cooper
Date: 02/01/2019

Desc: This is for sending periodic status messages as per Consat request.  This is subject to change with regards to
is sent but this is expected to be a big fat JSON file containing almost everything!

"""
import os
import json
import datetime

from datetime import datetime

class StatusHandler(object):
    def __init__(self, hw_dict, config_dict):

        self.config_dict = config_dict
        self.hw_dict = hw_dict
        self.statusDict = None
        self.JSONStatus = None

    def getSystemUptime(self):
        """
        Returns how long the system has been up in seconds.

        /proc/uptime returns two values, uptime and idletime, this returns the first value if successful else returns 0
        """

        filepath = "/proc/uptime"

        try:
            with open(filepath, "r") as _uptime:
                raw_uptime = _uptime.read()
                uptime = raw_uptime.rstrip().split(" ")[0]
        except FileNotFoundError:
            return 0
        except IndexError:
            return 0
        else:
            return uptime

    def get_timestamp(self):
        """
        Obtains the current Linux time and converts it into an epoch timestamp.
        Returns
        -------
        The timestamp
        """
        now = datetime.now()

        return datetime.timestamp(now)

    def get_mac_as_string(self):
        """
        Returns the MAC address without the colons
        """
        return self.hw_dict["unit_MAC"].replace(":", "")

    """
    #######################################################################################################################
    Hanover Specific functions
    #######################################################################################################################
    """
    def save_status_file(self, status_json: str):
        """
        This saves the status to a file so that it can be interrogated without additional tools
        """
        #Check if function is needed
        if "oniondebug_savestatus" in os.listdir("/tmp"):
            log_path = r"/tmp/hanip_status.txt"

            with open(log_path, "w") as log_file:
                log_file.write(status_json)

    def get_sign_status(self, lastUpdate, ecoStatus, ign_status, ign_off_time, sign_status):
        """
        This generates the sign status json.
        """
        try:
            short_status = sign_status[0]
            ext_status = sign_status[1]
        except IndexError:
            short_status = "NA"
            ext_status = "NA"

        self.statusDict = {
            "activeStateID": None,
            "lastupdate": lastUpdate,
            "status": {
                "uptime": self.getSystemUptime(),
                "ecoEnabled": ecoStatus,
                "ignition_state": ign_status,
                "ignition_off_time": ign_off_time,
                "status": short_status,
                "ext_status": ext_status,
                "hw_details": self.hw_dict,
            },
            "extensions": self.config_dict,
        }

        JSONStatus = json.dumps(self.statusDict,indent=4, separators=(',', ': '))
        self.JSONStatus = JSONStatus
        self.save_status_file(JSONStatus)
        return self.JSONStatus

    def get_console_status(self, lastUpdate, dest_data):
        self.statusDict = {
            "activeStateID": None,
            "lastupdate": lastUpdate,
            "status": {
                "uptime": self.getSystemUptime(),
                "ecoEnabled": None,
                "console_statuses": dest_data,
                "hw_details": self.hw_dict,
            },
            "extensions": self.config_dict,
        }

        JSONStatus = json.dumps(self.statusDict,indent=4, separators=(',', ': '))
        self.JSONStatus = JSONStatus
        self.save_status_file(JSONStatus)

        return self.JSONStatus

    """
    #######################################################################################################################
    VT MQTT Specific functions
    #######################################################################################################################
    """

    def generate_vt_config_message(self):
        """
        This is the hardware configuration of the sign, the type of sign, resolution, including colour information,
        network and serial.

        This payload will change depending on the type of sign it is running on, whether it is mono, colrn or fc
        :return:
        """
        width, height = self.hw_dict["sign_size"].split("x")

        try:
            _width_int = int(width)
        except ValueError:
            _width_int = 41

        vt_config_dict = {
            "logicalAddress": self.hw_dict["address"],
            "matrix": {
                "elementType": "LED",
                "resolution": {
                    "height": height,
                    "width": width
                },
            },
            "network": {
                "ipAddress": self.hw_dict["unit_IP"],
                "macAddress": self.hw_dict["unit_MAC"]
            },
            "serialNumber": self.hw_dict["serial_number"],
            "intendedDisplayContent": {
                "primaryContentType": "LINE_DEST" if _width_int > 40 else "LINE",
                "visibilityType": "EXTERIOR" if self.hw_dict["hw_type"] == "ext" else "INTERIOR"
            }
        }

        if self.hw_dict["colour_resolution"] != None:
            vt_config_dict["matrix"]["selectableColours"] = {
                "colourModel": "RGB",
            }

            col_width, col_height = self.hw_dict["colour_resolution"].split("x")
            if col_width != width:
                vt_config_dict["matrix"]["selectableColours"]["partialColourArea"] = {
                    "alignment": self.hw_dict["colour_alignment"],
                    "height": col_height,
                    "width": col_width
                }

        vt_config = json.dumps(vt_config_dict, indent=4, separators=(',', ': '))

        return vt_config

    def generate_vt_system_message(self):
        """
        New (configurable) topic to comply with the general requirements (see VT-MQTT chapter 7.3):  /system/hanover/[id*] having separate subtopics

        This needs to be returned as a dictionary!
        :return:
        """
        system_topic_dict = {
            "manufacturer": "Hanover Displays",
            "model": self.hw_dict["model"],
            "hwversion": self.hw_dict["hardware_version"],
            "mac": self.hw_dict["unit_MAC"],
            "ip4addr": self.hw_dict["unit_IP"],
            "swversion": self.hw_dict["onion_ver"]
        }

        return system_topic_dict

    """
    #######################################################################################################################
    Storstockholms Lokaltrafik, SL (Stockholm PTA) SR2638 Specific functions
    #######################################################################################################################
    """
    def generate_storstockholms_status_message(self):
        """
        Topic tobs/provider_clients/<client_id>/software

        And the payload will be:
        { "version": "1.2.3", "description": <description> }

        And the <description> is :
        { "name": "C3 service", "supplier": "ObservIT", "serialNumber": "acc:2cc81b27fd36", "extra": {<extra>} }

        And the <extra> is:
        {"key": "value"} other available information about HW or SW (not mandatory)

        To be sent every 300 seconds (5 mins)

        """
        unique_id = "hanover_" + self.get_mac_as_string()
        topic = self.config_dict.get("MQTT_sl_status_topic", "tobs/provider_clients/$MAC/software")

        topic = topic.replace("$MAC", unique_id)

        sl_status_dict = {
            "version": self.hw_dict["onion_ver"],
            "description": {
                "name": "",
                "supplier": "Hanover Displays",
                "serialNumber": self.hw_dict["serial_number"],
                "extra": {
                    "version_host": self.hw_dict["software_version"]
                }
            }
        }

        sl_status = json.dumps(sl_status_dict, indent=4, separators=(',', ': '))

        return sl_status, topic

    def generate_slmqtt_status_message(self):
        """

        """
        return self.generate_storstockholms_status_message()

if __name__ == "__main__":
    hw_dict = {
        "onion_ver": "",
        "serial_number": "",
        "software_version": "NA",
        "hardware_version": "NA",
        "superx_version": "2.2",
        "model": "",
        "address": "0",
        "sign_size": "160x24",
        "colour_resolution": None,
        "colour_alignment": None,
        "hw_status": "1",
        "hw_type": "ext",
        "unit_IP": "123.123.123.123",
        "unit_MAC": "00:00:00:00:00:00"
    }

    sh = StatusHandler(hw_dict, None)
    print(sh.generate_vt_config_message())
    print(sh.generate_vt_system_message())
