"""
Name: avms_to_ibisip
Title: AVMS to IBISIP
Author: Cooper
Date: 26/08/2025

Desc:  The backstory for this is that Trasndev have a working IBISIP delivery, but want to change it to AVMS.

The signs are connected via RS485 which is why there needs to be work on EG4 as well.  To get things out quicker, the
idea was that the incomming AVMS payload would be converted into a compatible IBISIP on.

This needs to subscribe to the AVMS module on the IVU, take the PlannedPattern and convert it into an IBISIP GetCurrentDisplayContent payload

This then needs to be funneled into the right places.

Originally planned to modify the keolis_avms stuff but that is responsible for dealing with sign data too, not just a simple
destcode set and forget.


The mapping between ITxPT and IBISIP elements are 1:1 as close as possible.
For example LineName in AVMS is mapped to the equivalent LineName in IBISIP.

"""
import json
import time
import _thread
import logging

import xmltodict

from hanip.itxpt import itxpt_avms
from hanip.itxpt import itxpt_mqtt

class AVMStoIBISIP(object):
    def __init__(self, config_dict, hw_dict, conf_dir, data_dir):
        self.config_dict = config_dict
        self.hw_dict = hw_dict
        self.conf_dir = conf_dir
        self.data_dir = data_dir

        self.republish_frequency = 5

        try:
            self.init_g4()
        except ImportError:
            self.eg4_mode = False
        else:
            self.eg4_mode = True

    def init_g4(self):
        # Attempt to connect to the g4 console application.
        from __main__ import G4_CONSOLE
        logging.info("G4: Initialising")
        self.g4hook = G4_CONSOLE()

    def setup_avms_client(self):
        """
        Sets up the client
        :return:
        """
        self.config_dict["AVMS_basic_mode"] = True
        self.config_dict["AVMS_self_consumption"] = False

        self.itxpt_avms = itxpt_avms.ITxPTAVMS(self.config_dict,
                                                 self.hw_dict,
                                                 self.conf_dir,
                                                 self.data_dir
                                                 )

        _thread.start_new_thread(self.itxpt_avms.run, ())

    def setup_mqtt_client(self):
        """
        Sets up the MQTT client so at least we can see what is going on even though sign data is not directly published here.
        """
        self.itxpt_mqtt = itxpt_mqtt.ConsoleMQTT(self.config_dict,
                                                 self.hw_dict,
                                                 self.conf_dir,
                                                 self.data_dir
                                                 )

        self.itxpt_mqtt.setup_mqtt_client()
        self.itxpt_mqtt.setup_status_handler()

    def generate_console_status(self):
        """
        Generates a status payload onto the local broker so that we can see the config parameters and the status of the
        AVMS client
        """
        publish_topic = self.config_dict.get("MQTT_status_topic", "infohub/dpi/sign/status/#/json").replace("#", "Console")

        avms_status = {
            "service_found": self.itxpt_avms.avms_server_found,
            "service_subscribed": self.itxpt_avms.avms_operation_details["plannedpattern"]["subscribed"],
            "service_ip": self.itxpt_avms.service_ip,
            "service_port": self.itxpt_avms.service_port,
            "service_errors": self.itxpt_avms.http_error,
            "note": "Check the config for static AVMS parameters"
        }

        console_data = {
            "avms_status": avms_status,
        }

        current_status = self.itxpt_mqtt.status_handler.get_console_status(time.time(), console_data)
        self.itxpt_mqtt.mqttc.publish_data(publish_topic, current_status)

    def generate_ibisip_payload(self, avms_data_dict):
        """
        Converts the data obtained via AVMs into an IBISIP payload
        """
        destination_text_list = []
        destination_text = avms_data_dict.get("DestinationLongName", " ")

        if destination_text is not None:
            destination_text = destination_text.split("\n")

            for text in destination_text:
                destination_text_list.append({'Value': text, 'Language': 'de'})
        else:
            destination_text_list.append({'Value': " ", 'Language': 'de'})

        # print(destination_text)

        ibisip_xml_dict = {
            "CustomerInformationService.GetCurrentDisplayContentResponse": {
                "CurrentDisplayContentData": {
                    "TimeStamp": {
                        "Value": avms_data_dict["RecordedAtTime"]
                    },
                    "CurrentDisplayContent": {
                        "CurrentDisplayContent": {
                            "Value": ""
                        },
                        "LineInformation": {
                            "LineRef": {
                                "Value": avms_data_dict.get("PublishedLineLabel", " ")
                            },
                            "LineName": {
                                "Value": avms_data_dict.get("LineName", " ")
                            },
                            "LineShortName": {
                                "Value": avms_data_dict.get("LineShortName", " ")
                            },
                            "LineNumber": {
                                "Value": avms_data_dict.get("ExternalLineRef", " ")
                            }
                        },
                        "Destination": {
                            "DestinationRef": {
                                "Value": ""
                            },
                            "DestinationName": destination_text_list
                        }

                    }
                }
            }
        }


        if self.eg4_mode:
            ibisip_xml = xmltodict.unparse(ibisip_xml_dict)
            # print(ibisip_xml)
            self.g4hook.process_ibis_ip_xml(ibisip_xml)

        # print(ibisip_xml_dict)

    def check_avms(self):
        """
        Checks the AVMS to see if there is new data and if there is then deal with it
        """
        if self.itxpt_avms.avms_operation_details["plannedpattern"]["new_data"]:
            print("AVMS: \tPlannedPattern new data")
            self.itxpt_avms.data_consumer.parse_planned_pattern(self.itxpt_avms.avms_operation_details["plannedpattern"]["raw_xml_data"])
            self.itxpt_avms.avms_operation_details["plannedpattern"]["new_data"] = False

            avms_data_dict = self.itxpt_avms.data_consumer.planned_pattern_dict

            if avms_data_dict is not None:
                self.generate_ibisip_payload(avms_data_dict)

    def run(self):
        """
        Main loop
        """
        self.setup_mqtt_client()
        self.setup_avms_client()

        status_timer = 0

        while 1:
            self.check_avms()

            if time.time() - status_timer > 30:
                print("Publishing status")
                status_timer = time.time()
                self.generate_console_status()

            time.sleep(1)


if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)

    configs = {
    }

    hw = {
        "unit_IP": "10.104.0.37",
        "hw_type": "con",
        "serial_number": "0121do1"
    }

    from hanip.itxpt import avms_data_consumer
    adc = avms_data_consumer.AVMSDataConsumer(debug=False)

    atoi = AVMStoIBISIP(configs, hw, "", "")

    import os

    xml_file_path = r"C:\Users\cchan\OneDrive - Hanover Displays Ltd\Documents\Cooper's Work Files\^Projects\^Protocols\IBIS-IP\IVU Tdev NL"
    xml_files = os.listdir(xml_file_path)
    xml_files.sort()

    for xml_file in xml_files:
        xml_data = open(os.path.join(xml_file_path, xml_file), "r").read()
        print("Using ", xml_file)

        avms_dict = adc.parse_planned_pattern(xml_data)

        print(adc.planned_pattern_dict)
        # with open(os.path.join(r"C:\temp", xml_file + ".json"), "w") as output_json_file:
        #     output_json_file.write(json.dumps(avms_dict))

        atoi.generate_ibisip_payload(adc.planned_pattern_dict)


