"""
Author: Cooper
Date: 15/03/2019

Desc: Parses configuration files into the form of a dictionary.

Deals with all configuration files apart from signGraphics.cfg.

"""
import os
import configparser

class OnionConfig(object):
    """
    Class to parse the configuration file into a dictionary.

    Member variables
    ----------------
    valid_config : bool
        Flag to indicate that the attempt to read the file and parse it was ok, or not.
    config : RawConfigParser
        The configparser instance used to process the file.
    config_dict : dict
        The output dictionary containing all parsed items.

    """

    def __init__(self):
        """
        Sets valid_config to False to ensure that failures fail properly.

        """

        self.valid_config = False

    def parse_configs_dict(self, configpath, configname):
        """
        Carries out the parsing operation.

        Translates text depiction of booleans into actual boolean values.

        Parameters
        ----------
        configpath : str
            The directory where the configuration file will be found.
        configname : str
            The filename of the file to parse.

        Returns
        -------
            The dictionary of configuration items, or an empty dict if parsing fails.
        """

        self.config = configparser.RawConfigParser()
        config_path = os.path.join(configpath, configname)
        print("Config: Using config: " + config_path)
        self.config.read(config_path)

        self.config_dict = {}

        try:
            self.valid_config = self.config.get("EOF", "complete")
        except configparser.Error as e:
            print("Config Error: %s" % e)
        else:
            self.valid_config = True
            for section in self.config.sections():
                for (key, value) in self.config.items(section):
                    if value == "True":
                        self.config_dict["%s_%s" % (section, key)] = True
                    elif value == "False":
                        self.config_dict["%s_%s" % (section, key)] = False
                    else:
                        self.config_dict["%s_%s" % (section, key)] = value
        return self.config_dict

    def merge_configs(self, oconf, cloud_conf):
        """
        Merges two config dicts into one single one.  This permits cloud parameters to be kept on a separate file
        """
        return {**oconf, **cloud_conf}

class ConsatConfiguration(object):
    def __init__(self):
        self.consat_config_dict = {
            "CONFIG": {
                "name": "itxpt_consat_default",
                "desc": "This copy is automatically generated for upgrade purposes",
                "date": "",
            },

            "NETWORK": {
                "dhcp_server": "False",
                "dhcp_client": "True",
                "local_link_address": "False",
                "fallback_timeout": "3",
                "static_ip": "192.168.3.100",
                "wait_for_network": "True",
                "unix_device": "br-lan"
            },

            "MODE": {
                "service_mode": "mqtt"
            },

            "MQTT": {
                "discover": "False",
                "timeout": "2",
                "service_type": "_mqtt._tcp.local.",
                "hostname": "Han_con",
                "primary_hostname": "Han_con",
                "fallback_address": "192.168.3.30",
                "broker_topic": "infohub/dpi/sign/request/#/json",
                "reply_topic": "infohub/dpi/sign/response/#/json",
                "status_topic": "infohub/dpi/sign/status/#/json"
            },

            "BRIGHTNESS": {
                "brightness_gain": "10",
                "max_brightness": "100",
                "min_brightness": "5"
            },

            "ECOMODE": {
                "enable": "True",
                "blank_after": "1",
                "blanking_level": "30"
            },

            "RENDERBOX": {
                "enable": "False"
            },

            "SERIAL": {
                  "baudrate_host_console": "115200",
                  "baudrate_host_sign": "38400",
                  "baudrate_rs485": "38400",
                  "unix_comport": "/dev/ttyS1",
                  "rs485_comport": "/dev/ttyS2"
            },

            "EOF": {
                "complete": "1"
            }
        }

    def generate_consat_configuration(self, configpath: str = "", configname: str = ""):
        """
        The idea of this is to allow the system to generate a Consat compatible configuration
        """
        config = configparser.ConfigParser()

        for section in self.consat_config_dict.items():
            section_name = section[0]
            section_dict = section[1]

            config.add_section(section_name)

            for parameters in section_dict.items():
                parameter_name = parameters[0],
                parameter_value = parameters[1]
                # print(section_name, parameter_name[0], parameter_value)
                config.set(section_name, parameter_name[0], parameter_value)

        if configpath == "":
            configpath = "/etc/hanip/"
        if configname == "":
            configname = "config.cfg"

        try:
            configfile = open(os.path.join(configpath, configname), "w")
            config.write(configfile)
        except OSError:
            print("Oconf: Cannot write config")
            return 1
        else:
            self.set_network_flag()
            return 0

    def set_network_flag(self):
        """
        Sets the network flag so that networkconfigurator is bypassed
        """
        try:
            networkflag = open(os.path.join("/etc/hanip", "network.done"), "w")
            networkflag.close()
            print("Oconf: Network flag set")
        except OSError:
            print("Oconf:Cannot set network flag...")

if __name__ == "__main__":
    onionconf = OnionConfig()
    cdict = onionconf.parse_configs_dict(r"C:\git\hanip\test_scripts\configs", "config.cfg")
    print(cdict)
    print(onionconf.valid_config)

    clouddict = onionconf.parse_configs_dict(r"C:\git\hanip\test_scripts\configs", "cloud.cfg")
    print(clouddict)

    print(onionconf.merge_configs(cdict, clouddict))

    consatconf = ConsatConfiguration()
    consatconf.generate_consat_configuration(r".C:\git\hanip\test_scripts\configs", "config.cfg")

