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

# Copyright 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
import re
import glob
from calculate.lib.cl_template import TemplateFormat

from calculate.lib.cl_lang import setLocalTranslate
from calculate.lib.utils.common import getTupleVersion
from calculate.lib.utils.content import PkgContents
from calculate.lib.utils.portage import getInstalledAtom
from calculate.lib.utils.files import pathJoin
from calculate.lib.utils.tools import classificate

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


class contents(TemplateFormat):
    """
    Формат для модификации принадлежности файлов пакетам
    """
    text = ""

    def textToXML(self):
        return self.text

    def processingFile(self, textConfigFile, rootPath=None):
        """Обработка конфигурационного файла"""
        reRule = re.compile("^(!?)(\S+)\s+(.+)$")
        cache_content = {}
        if not rootPath:
            rootPath = '/'
        try:
            for line in (x for x in self.text.split("\n")
                         if not x.startswith("#")):
                line = line.strip()
                if not line:
                    continue
                rule_match = reRule.search(line)
                if not rule_match:
                    self.setError(_("Wrong 'contents' format rule: %s") % line)
                    return False
                remove_act, atom, fn_glob = rule_match.groups()
                if "," in atom and remove_act:
                    self.setError(_("Wrong 'contents' format rule: %s") % line)
                    return False
                atom_source, _op, atom_target = atom.partition(",")
                source_data = {}
                # если перевод привязки
                if atom_target:
                    remove_act = True
                for mark, pkg in classificate(sorted(
                        getInstalledAtom(atom_source, prefix=rootPath),
                        key=lambda x: getTupleVersion(x['PVR']))):
                    # добавляем файл только к пакету со старшей версией
                    if not remove_act and not mark.last:
                        continue
                    pn = str(pkg)
                    if pn not in cache_content:
                        cache_content[pn] = PkgContents(pn, prefix=rootPath)
                    pkg_contents = cache_content[pn]
                    if remove_act:
                        for fn, data in pkg_contents.removeGlobObject(fn_glob):
                            if atom_target:
                                source_data[pathJoin(rootPath, fn)] = data
                    else:
                        prefix_fn_glob = pathJoin(rootPath, fn_glob)
                        for fn in glob.glob(prefix_fn_glob):
                            pkg_contents.addObject(fn)
                if atom_target:
                    for pkg in sorted(
                            getInstalledAtom(atom_target, prefix=rootPath),
                            key=lambda x: getTupleVersion(x['PVR']))[-1:]:
                        pn = str(pkg)
                        if pn not in cache_content:
                            cache_content[pn] = PkgContents(pn, prefix=rootPath)
                        pkg_contents = cache_content[pn]
                        for fn in source_data:
                            pkg_contents.addObject(fn)
                            pkg_contents.updateData(fn, source_data[fn])
        finally:
            for pkg_contents in cache_content.values():
                pkg_contents.writeContents()
        return ""
