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

# Copyright 2008-2012 Calculate Ltd. 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 re
from calculate.lib.cl_template import blocText, xmlDoc
from calculate.lib.format.samba import samba

class ldap(samba):
    """Класс для обработки конфигурационного файла типа ldap

    """
    _comment = "#"
    configName = "ldap"
    configVersion = "0.1"
    # Регулярное выражение для заголовка области
    reHeader = re.compile("^[\t ]*(access|syncrepl)[^\n]+\n?")
    # Регулярное выражения для области
    reArea = re.compile("([\t ]*(access|syncrepl)[^\n]+\
\n([\t ]+[^\n]+\n?)+)",re.M|re.S)
    reComment = re.compile("\s*%s.*"%(_comment))
    # разделитель между переменной и значением переменной
    reSeparator = re.compile("\s+")
    # разделитель полей
    sepFields = "\n"
    # регулярное выражение для разделителя полей
    reSepFields = re.compile(sepFields)

    def __init__(self,text):
        self.text = text
        self.blocTextObj = blocText()
        self._splitToFields =  self.splitToFields
        # Объект документ
        self.docObj = self._textToXML()
        # Создаем поля-массивы
        self.docObj.postParserList()
        # Создаем поля разделенные массивы
        self.docObj.postParserListSeplist(self.docObj.body)
        # XML документ
        self.doc = self.docObj.doc

    def join(self, ldapObj):
        """Объединяем конфигурации"""
        if isinstance(ldapObj, ldap):
            self.docObj.joinDoc(ldapObj.doc)

    def setDataField(self, txtLines, endtxtLines):
        """Создаем список объектов с переменными"""
        class fieldData:
            def __init__(self):
                self.name = False
                self.value = False
                self.comment = False
                self.br = False
        fields = []
        field = fieldData()
        z = 0
        for k in txtLines:
            textLine = k + endtxtLines[z]
            z += 1
            findComment = self.reComment.search(textLine)
            if not textLine.strip():
                field.br = textLine
                fields.append(field)
                field = fieldData()
            elif findComment:
                field.comment = textLine
                fields.append(field)
                field = fieldData()
            else:
                pars = textLine.strip()
                nameValue = self.reSeparator.split(pars)
                if len(nameValue) > 2:
                    valueList = nameValue[2:]
                    nameValue =[nameValue[0]+nameValue[1]," ".join(valueList)]
                if len(nameValue) == 2:
                    name = nameValue[0]
                    value = nameValue[1].replace(self.sepFields,"")
                    field.name = name.replace(" ","").replace("\t","")
                    field.value = value
                    field.br = textLine
                    fields.append(field)
                    field = fieldData()
        return fields

    def _textToXML(self):
        """Преобразует текст в XML"""
        blTmp = self.blocTextObj.findArea(self.text,self.reHeader,self.reArea)
        blocs = self.getFullAreas(blTmp)
        headers = []
        startHeaders = []
        finHeaders = []
        docObj = xmlDoc()
        docObj.createDoc(self.configName, self.configVersion)
        rootNode = docObj.getNodeBody()
        # Если пустой текст то создаем пустой документ
        if not blocs:
            return docObj

        for h in blocs[0]:
            headers.append(h.rstrip())
        bodys = blocs[1]

        z = 0
        for h in headers:
            if not bodys[z]:
                z += 1
                continue
            areaAction = False
            if h:
                if h[0] == "!":
                    header = self.removeSymbolTerm(h.strip())
                    headerQuote = self.removeSymbolTerm(h)
                    docObj.createCaption(header,[headerQuote,""])
                    areaAction = "drop"
                elif h[0] == "-":
                    header = self.removeSymbolTerm(h.strip())
                    headerQuote = self.removeSymbolTerm(h)
                    docObj.createCaption(header,[headerQuote,""])
                    areaAction = "replace"
                else:
                    docObj.createCaption(h.strip(), [h.rstrip(),""])
            else:
                docObj.createCaption(h.strip(), [h.rstrip(),""])

            if "\n" in blocs[0][z]:
                resHead = self.reComment.search(h)
                if resHead:
                        docObj.createField('comment',
                        blocs[0][z][resHead.start():])
                else:
                    docObj.createField('br')

            fields = self._splitToFields(bodys[z])
            for f in fields:
                if f.name != False and f.value!=False and f.br!=False:
                    # Обработка условий для samba
                    if f.name[0] == "!" or f.name[0] == "-" or\
                        f.name[0] == "+":
                        qns = self.removeSymbolTerm(f.br)
                        xmlField = docObj.createField("var",
                                                  [qns],
                                                  f.name[1:], [f.value])
                        if f.name[0] == "!":
                            # Удаляемое в дальнейшем поле
                            docObj.setActionField(xmlField, "drop")
                        elif f.name[0] == "+":
                            # Добавляем уникальное поле
                            xmlField.setAttribute("type", "seplist")
                            docObj.setActionField(xmlField, "join")
                    else:
                        docObj.createField("var",[f.br.replace("\n","")],
                                           f.name, [f.value])
                    docObj.createField('br')
                elif f.comment != False:
                    docObj.createField('comment', [f.comment])
                elif f.br != False:
                    docObj.createField('br', [f.br.replace("\n","")])
            if h.strip():
                area = docObj.createArea()
                if areaAction:
                    docObj.setActionArea(area, areaAction)
                rootNode.appendChild(area)
            else:
                fieldsNodes = docObj.tmpFields.getFields()
                for fieldNode in fieldsNodes:
                    rootNode.appendChild(fieldNode)
                docObj.clearTmpFields()
            z += 1
        return docObj
 
