#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
###########################################################################
# Eole NG - 2016
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
#
# purge_backup.py
#
# script de nettoyage des données obsolètes après restauration d'une
# sauvegarde provenant d'une version < 2.6.0
#
###########################################################################

import os
from glob import glob
from zephir.backend.lib_backend import CxPool


def purge_db(cx_pool, modules, variantes, serveurs):
    """ Nettoyage de la base de données
    """

    cu = cx_pool.create()
    # serveurs: réinitialisation de module_initial si c'est un module non supporté
    for id_mod in modules:
        cu.execute("update serveurs set module_initial=module_actuel where \
                    module_initial={}".format(id_mod))
    cx_pool.commit(cu)
    # Nettoyage des tables liées à ces ressources dont la clé étrangère
    # n'est pas en 'CASCADE DELETE'
    # serveurs: ent_id_ranges / restrictions
    cu = cx_pool.create()
    for serv in serveurs:
        cu.execute("delete from ent_id_ranges where serveur={}" \
                   .format(serv['id']))
        cu.execute("delete from restrictions where id_res='{}' \
                   and type_res='serveur'".format(serv['id']))
    # modules/variantes : restrictions
    for id_mod in modules:
        cu.execute("delete from restrictions where id_res='{}' \
                   and type_res='module'".format(id_mod))
    for id_var in variantes:
        cu.execute("delete from restrictions where id_res='{}' \
                   and type_res='module'".format(id_var))
    cx_pool.commit(cu)
    # suppression des serveurs dans les groupes
    cu = cx_pool.create()
    cu.execute("select id, serveurs from groupes_serveurs")
    groupes = cu.fetchall()
    serveurs_ids = set([serv['id'] for serv in serveurs])
    for gr_id, gr_serv in groupes:
        # suppression des serveurs obsolètes dans tous les groupes enregistrés
        liste_serv = set(eval(gr_serv))
        cleared_list = list(liste_serv.difference(serveurs_ids))
        cu.execute("update groupes_serveurs set serveurs='{}' where id={}"\
                   .format(str(cleared_list), gr_id))
    cx_pool.commit(cu)

    # Suppression des serveurs/modules/variantes non gérés
    cu = cx_pool.create()
    for serv in serveurs:
        cu.execute("delete from serveurs where id={}".format(serv['id']))
    for id_var in variantes:
        cu.execute("delete from variantes where id={}".format(id_var))
    for id_mod in modules:
        cu.execute("delete from modules where id={}".format(id_mod))
    cx_pool.commit(cu)

def purge_files(modules, variante, serveurs):

    ###############
    # ARBORESCENCE

    # fichiers supprimés à partir de 2.6.0
    to_del = ["/var/lib/zephir/site"]
    to_del.append("/var/lib/zephir/xml")
    # cache des paquets disponibles
    if glob("/var/lib/zephir/packages_eole_2.[0-3]_*.ini"):
        to_del.extend(glob("/var/lib/zephir/packages_*.ini"))
        to_del.extend(glob("/var/lib/zephir/md5maj_*.ini"))
    if serveurs:
        # Fichiers spécifiques aux serveurs
        serveur_files = ["/var/lib/zephir/data/packages_{id}.list",
                         "/var/lib/zephir/data/config{id}.md5"]
        serveur_dirs = ["/var/lib/zephir/data/{id}",
                        "/var/lib/zephir/conf/{rne}/{id}",
                        "/var/spool/uucp/{rne}-{id}"]
        for serv in serveurs:
            to_del.append("/etc/uucp/serveurs/{rne}-{id}.sys".format(**serv))
            for serv_fic in serveur_files:
                if os.path.isfile(serv_fic.format(**serv)):
                    to_del.append(serv_fic.format(**serv))
            for serv_dir in serveur_dirs:
                if os.path.isdir(serv_dir.format(**serv)):
                    to_del.append(serv_dir.format(**serv))

        # Ménage dans les fichiers de configuration UUCP
        uucp_conf = open("/etc/uucp/config_zephir").read()
        for serv in serveurs:
            uucp_conf = uucp_conf.replace(
                '\nsysfile /etc/uucp/serveurs/{rne}-{id}.sys'.format(**serv), '')
            uucp_pass = open("/etc/uucp/passwd_zephir").readlines()
            passwd = []
            for pass_line in uucp_pass:
                if not pass_line.startswith('{rne}-{id} {rne}-{id}-'.format(**serv)):
                    passwd.append(pass_line)
            pass_f = open("/etc/uucp/passwd_zephir", "w")
            pass_f.writelines(passwd)
            pass_f.close()
        conf_f = open("/etc/uucp/config_zephir", "w")
        conf_f.write(uucp_conf)
        conf_f.close()

    # Fichiers spécifiques aux distributions
    for dist_id in range(11):
        if os.path.isdir("/usr/share/zephir/default_modules/{}"\
                         .format(dist_id + 1)):
            to_del.append("/usr/share/zephir/default_modules/{}"\
                          .format(dist_id + 1))

    # Fichiers spécifiques aux modules
    for mod_id in modules:
        to_del.append("/var/lib/zephir/modules/{}".format(mod_id))

    # Répertoires des dictionnaires
    to_del.append("/usr/share/zephir/dictionnaires/2.{4..5}*")

    # suppression de tous les fichiers /répertoires listés
    for fic_del in to_del:
        res = os.system('rm -rf {} >/dev/null'.format(fic_del))
        if res != 0:
            print("Erreur de suppression de {}".format(fic_del))

def main():
    """
    * Récupere les id de modules/variantes/serveurs correspondants au versions <= 2.5.2
    * purge la base de données
    * purge le système de fichiers
    """
    cx_pool = CxPool()
    cu = cx_pool.create()
    cu.execute("""select id from modules where version < 20""")
    modules = [module[0] for module in cu.fetchall()]
    cu.execute("""select serveurs.id, serveurs.rne from serveurs, modules \
        where serveurs.module_actuel=modules.id and modules.version < 20""")
    serveurs = [{'id':serveur[0], 'rne':serveur[1]} for serveur in cu.fetchall()]
    cu.execute("""select variantes.id from variantes, modules where \
               variantes.module=modules.id and modules.version < 20""")
    variantes = [variante[0] for variante in cu.fetchall()]
    cx_pool.close(cu)
    if len(modules) + len(variantes) + len(serveurs) > 0:
        # des données obsolètes existent en base
        purge_db(cx_pool, modules, variantes, serveurs)
    purge_files(modules, variantes, serveurs)
    # suppression du fichier .imported après nettoyage
    if os.path.isfile('/var/lib/zephir/.restored'):
        os.unlink('/var/lib/zephir/.restored')


if __name__ == '__main__':
    main()
