# -*- coding: utf-8 -*-

# Copyright 2015-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
from calculate.lib.cl_template import TemplateFormat
from calculate.lib.cl_lang import setLocalTranslate
from collections import OrderedDict

_ = lambda x: x
setLocalTranslate('cl_lib3', sys.modules[__name__])


class kernel(TemplateFormat):
    """Класс для объединения файлов конфигурации ядра"""
    # root нода
    rootNode = False
    # body нода
    bodyNode = False
    # Документ
    doc = False
    # Текст шаблона
    text = ""
    # Комментарий
    _comment = "#"

    def prepare(self):
        # Создаем пустой объект
        self.docObj = type("_empty_class", (object,), {})()
        # Названия аттрибутов для пустого объекта
        emptyMethods = ["getNodeBody", "removeComment", "insertBRtoBody",
                        "insertBeforeSepAreas"]
        # Добавляем необходимые аттрибуты пустому объекту
        for method in emptyMethods:
            setattr(self.docObj, method, self.emptyMethod)
        # Создаем XML документ
        self.doc = self.textToXML()

    def emptyMethod(self, *arg, **argv):
        """Пустой метод"""
        return True

    def textToXML(self):
        """Создание документа из текста self.text
        """

        class KernelConfig:
            def __init__(self):
                self.body = OrderedDict()
                self.remove = []

        doc = KernelConfig()
        for line in (x for x in self.text.split('\n')
                     if x.strip() and ("is not set" in x or
                                       not x.startswith(self._comment))):
            if "is not set" in line:
                key, op, value = line[2:].strip().partition(' is not set')
                value = 'n'
            else:
                key, op, value = line.strip().partition('=')
            if key[:1] == '!':
                doc.remove.append(key[1:])
            else:
                doc.body[key] = value
        return doc

    def join(self, xml_xfceObj):
        """Объединяем конфигурации"""
        if isinstance(xml_xfceObj, kernel):
            try:
                self.joinDoc(xml_xfceObj.doc)
            except Exception:
                self.setError(_("Failed to join the template"))
            return False
        return True

    def postXML(self):
        """Последующая постобработка XML"""
        pass

    def _join(self, xmlNewNode, xmlOldNode):
        """Объединение корневой ноды шаблона и корневой ноды файла"""
        xmlOldNode.body.update(xmlNewNode.body)
        for opt in xmlNewNode.remove:
            xmlOldNode.body.pop(opt, None)
        return True

    def joinDoc(self, doc):
        """Объединение документа шаблона и документа файла"""
        if not self.doc:
            self.setError(_("The text file is not XML"))
            return False
        if not doc:
            self.setError(_("The text file is not XML"))
            return False
        # объединяем документы
        if not self._join(doc, self.doc):
            return False
        return True

    def getConfig(self):
        """Получение текстового файла из XML документа"""

        def getline(key, value):
            if value == 'n':
                return '# %s is not set\n' % key
            else:
                return '%s=%s\n' % (key, value)

        return "".join([getline(key, value)
                        for key, value in self.doc.body.items()]).decode(
            'UTF-8')
