# -*- coding: utf-8 -*-
"""
/***************************************************************************
 XMLConfigCtrl
                                 A QGIS plugin
 wide are mapping
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2020-11-13
        git sha              : $Format:%H$
        copyright            : (C) 2020 by forschung@ciss.de
        email                : forschung@ciss.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

from xml.dom import minidom as dom
import weissflaechenkartierung.src.xml.module as m


class XMLConfigCtrl:
    """
    handles the connection to the xml *.cfg
    """

    def __init__(self, xml_path: str = ""):
        """
        :param xml_path: path to the xml file
        """
        self._xml_dom = None
        self._c_type = None
        self._xml_path = None
        self.parse(xml_path=xml_path)

    def __str__(self):
        return "c_type: " + self._c_type + " xml_path: " + self._xml_path

    def parse(self, xml_path: str):
        """
        parses a new xml doc
        """
        if xml_path:
            self._xml_dom = dom.parse(xml_path).documentElement
            self._c_type = self.get_type_from_xml(self._xml_dom)
            self._xml_path = xml_path

    def main_dom(self):
        """
        returns the main parsed dom object
        """
        return self._xml_dom

    @property
    def xml_path(self):
        """
        returns the path to the xml-file
        """
        return self._xml_path

    def get_configuration_sections(self) -> list:
        """
        returns a list with configurations
        """
        return [XMLConfigCtrl.get_name_from_xml(ele) for ele in self._xml_dom.getElementsByTagName("config")]

    @staticmethod
    def get_modules_from_xml(element, config) -> list:
        """
        returns all modules of the element
        """
        return [m.Module(xml_section=mod,
                         config=config,
                         name=XMLConfigCtrl.get_name_from_xml(element=mod),
                         parameters=XMLConfigCtrl.get_parameter_from_xml(xml=mod),
                         active=XMLConfigCtrl.get_active_from_xml(xml_section=mod)
                         )
                for mod in element.getElementsByTagName("module")]

    @staticmethod
    def get_active_from_xml(xml_section) -> bool:
        """
        set the active status of the element
        """
        return XMLConfigCtrl.get_bool_value(xml_section.getAttribute("active"))

    @staticmethod
    def get_bool_value(value: str = "active", default: bool = True):
        if value is None:
            return default
        value = value.lower()
        if value == "ja" or value == "yes" or value == "wahr" or value == "true" or value == "1":
            return True
        if value == "nein" or value == "no" or value == "falsch" or value == "false" or value == "0":
            return False
        return default

    @staticmethod
    def get_type_from_xml(element) -> str:
        """
        returns the xml type
        """
        return element.getAttribute("type")

    @staticmethod
    def get_value_from_xml(element) -> str:
        """
        returns the value
        """
        return element.getAttribute("value")

    @staticmethod
    def get_name_from_xml(element) -> str:
        """
        returns the name of a configuration section
        """
        return element.getAttribute("name")

    def get_first_config_by_name(self, name: str = ""):
        """
        returns the first configuration by name

        :param name: name of the configuration
        """
        for ele in self._xml_dom.getElementsByTagName("config"):
            if self.get_name_from_xml(ele) == name:
                return ele
        return None

    @staticmethod
    def get_all_tags_in_child_nodes(xml, tag) -> list:
        """
        returns a list with all tags who match "tag"
        """
        tags: list = []
        for ele in xml.childNodes:
            if ele.nodeType != ele.ELEMENT_NODE:
                continue
            if ele.tagName == tag:
                tags.append(ele)
        return tags

    @staticmethod
    def get_first_tag_in_child_nodes(xml, tag):
        """
        returns the first tag in the child nodes
        """
        for ele in xml.childNodes:
            if ele.nodeType != ele.ELEMENT_NODE:
                continue
            if ele.tagName == tag:
                return ele
        return None

    @staticmethod
    def get_parameter_from_xml(xml) -> dict:
        out = {}
        if xml is None:
            return out

        for p in xml.childNodes:
            if p.nodeType != p.ELEMENT_NODE:
                continue
            if p.tagName != "parameter":
                continue
            key = p.getAttribute("key")
            value = p.getAttribute("value")
            if value == "__items__":
                value = [i.getAttribute("value") for i in p.getElementsByTagName("item")]
            out[key] = value
        return out
