# -*- 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 ..cl_template import TemplateFormat
from ..utils.text import _u
from ..cl_lang import setLocalTranslate
from os import path
import re

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


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

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

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

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

        def autocategory(name):
            if name and "/" not in name:
                prefix, op, name = name.rpartition("!")
                return "%s%s%s/%s" % (prefix, op, category, name)
            return name
        try:
            # doc = list(filter(None,
            #              [autocategory(x.strip()) for x in self.text.split("\n")
            #               if not x.startswith("#")]))
            doc = [z for z in [autocategory(x.strip()) for x in self.text.split("\n")
                          if not x.startswith("#")] if z]
        except ValueError:
            doc = False
        return doc

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

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

    def _join(self, new_doc, old_doc):
        """Объединение корневой ноды шаблона и корневой ноды файла"""
        for line in new_doc:
            if line.startswith("!"):
                pkg = line[1:]
                # если удаление с проверкой и предупреждением
                if pkg.startswith("!"):
                    warn = True
                    pkg = pkg[1:]
                else:
                    warn = False
                if pkg.endswith(":*"):
                    re_match = re.compile("^{0}$|^{0}:.*$".format(pkg[:-2])).match
                    remove_records = [x for x in old_doc if re_match(x)]
                    if remove_records:
                        for del_pkg in remove_records:
                            old_doc.remove(del_pkg)
                        warn = False
                    else:
                        warn &= True
                else:
                    if pkg in old_doc:
                        old_doc.remove(pkg)
                        warn = False
                    else:
                        warn &= True
                if warn:
                    if callable(self.parent.printWARNING):
                        self.parent.printWARNING(
                            _("Not found {package} in world").format(package=pkg))
            else:
                if line not in old_doc:
                    old_doc.append(line)
        return True

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

    def getConfig(self):
        """Получение текстового файла из XML документа"""
        return "%s\n" % "\n".join(sorted(self.doc))
