# -*- coding: utf-8 -*-
###########################################################################
# EOLE - 2011
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
#
# modifié par Cadoles (http://www.cadoles.com/)
# contact@cadoles.com
#
###########################################################################

from shutil import rmtree
from os import system, symlink, chown, remove, rename
from os.path import join, islink, isdir, exists, lexists
from pyeole.common import recurive_mode_makedirs as makedirs
import ldap

from scribe.ldapconf import ROOT_DN, ldap_passwd, SUFFIX, \
        HOME_PATH, USER_FILTER, GROUP_FILTER, SHARE_FILTER

class Ldap():
    def __init__(self):
        self.ldap_conn = ldap.initialize('ldap://{}'.format(self.serveur))
        self.ldap_conn.simple_bind_s(ROOT_DN, ldap_passwd)

    def ldap_search(self, ldap_filter, attrib=None, one=False):
        result = self.ldap_conn.search_s(SUFFIX, ldap.SCOPE_SUBTREE,
                                    ldap_filter, attrib)
        if len(result) > 0 and len(result[0]) == 2:
            if one:
                return result[0][1]
            else:
                return result
        else:
            return {}
    def get_user_attributs(self, user):
        return self.ldap_search("(&%s(uid=%s))" % (USER_FILTER, user),
                ['objectClass', 'homeDirectory', 'sambaHomeDrive', 'uidNumber',
                'gidNumber', 'displayName', 'sambaSID'], True)

    def get_groups(self, user):
        return self.ldap_search("(&%s(memberUid=%s))" % (GROUP_FILTER, user),
                attrib=['cn', 'gidNumber'])

    def get_group_name(self, gidnumber):
        return self.ldap_search("(&%s(gidNumber=%s))" % (GROUP_FILTER,
                gidnumber), ['displayName'], True)['displayName'][0]

    def get_shares_filtred(self, group_filter):
        return self.ldap_search('(&%s(|%s))' % (SHARE_FILTER, group_filter),
                    ['sambaShareName', 'sambaFilePath', 'sambaShareURI',
                    'sambaShareDrive'])

    def __del__(self):
        self.ldap_conn.unbind()
        del(self)

def get_userclass_name(objectClass):
    """
        Renvoie le nom du module gérant les objets de classe : objectClass
    """
    if objectClass == None:
        return None
    users_objectClass = {
            'Eleves': 'eleve',
            'administrateur': 'enseignant',
            'responsable': 'responsable',
            'administratif': 'administratif',
            'autre': 'autre',
            }
    for objectclass, module in users_objectClass.items():
        if objectclass in objectClass:
            return module
    return None

def gen_devdir(login, uid, homedir, userclass):
    """
        Partie commune pour _gen_devoirdir
    """
    if userclass not in ['eleve', 'enseignant']:
        return
    perso = join(homedir, 'perso')
    # le partage "devoirs" /home/l/login/devoirs
    dev_part = join(homedir, 'devoirs')
    # le dossier U:\devoirs /home/l/login/perso/devoirs
    dev_perso = join(perso, 'devoirs')
    cmd = ""
    for rep in [dev_part, dev_perso]:
        if not isdir(rep):
            makedirs(rep, 0o750)
            cmd += '/bin/chown -PR %s %s;' % (login, rep)
            cmd += '/usr/bin/setfacl -PRm u:%s:rwx %s;'%(uid, rep)
            cmd += '/usr/bin/setfacl -dPRm u:%s:rwx %s;'%(uid, rep)

    if userclass == 'enseignant':
        # dossier contenant les devoirs et les données à distribuer du prof
        # U:\devoirs\.distribues ou \\scribe\devoirs\.distribues
        devoirs = join(HOME_PATH, 'workgroups/devoirs')
        if not isdir(devoirs):
            raise Exception(f'Le répertoire "{devoirs}" n\'existe pas !')
        dev_dist_dir = join(devoirs, login)
        if not isdir(dev_dist_dir):
            makedirs(dev_dist_dir, 0o755)
            cmd += '/usr/bin/setfacl -PRbk %s;' % dev_dist_dir
            cmd += '/usr/bin/setfacl -PRm u:%s:rwx %s;' % (uid, dev_dist_dir)
            cmd += '/usr/bin/setfacl -dPRm u:%s:rwx %s;' % (uid, dev_dist_dir)
        for rep in [dev_part, dev_perso]:
            link = join(rep, '.distribues') # le cacher avec un "."
            if isdir(dev_dist_dir) and not islink(link):
                # si le lien existe et n'est pas un lien, le renommer en distribues.a_supprimer
                # si le répertoire distribues.a_supprimer existe déjà, le supprimer purement
                if lexists(link):
                    dstdir = join(rep, 'distribues.a_supprimer')
                    if not lexists(dstdir):
                        rename(link, dstdir)
                    else:
                        rmtree(link)
                symlink(dev_dist_dir, link)
    if cmd != '':
        system(cmd)

def gen_ftpdir(uid, homedir, shares):
    """
        Gestion du répertoire ".ftp"
    """
    ftpdir = join(homedir, '.ftp')
    ftpperso = join(ftpdir, 'perso')
    if homedir.startswith('/home'):
        homedir = join(HOME_PATH, homedir[6:])
    homeperso = join(homedir, 'perso')
    def create_ftpsymlink():
        if isdir(homeperso) and not islink(ftpperso):
            # si un répertoire .ftp/perso existe on supprime sans sauvegarde
            if lexists(ftpperso):
                rmtree(ftpperso)
            symlink(homeperso, ftpperso)
        for share in shares:
            if share['name'] not in ['icones$', 'groupes']:
                if HOME_PATH != '/home':
                    share['path'] = share['path'].replace('/home', HOME_PATH)
                orig_shared_path = share['path']
                shared_path = join(ftpdir, share['name'])
                if isdir(orig_shared_path):
                    if not exists(shared_path):
                        if lexists(shared_path):
                            remove(shared_path)
                        symlink(orig_shared_path, shared_path)
                elif islink(shared_path):
                    remove(shared_path)
    if not isdir(ftpdir):
        makedirs(ftpdir, 0o500)
        chown(ftpdir, uid, -1)
    elif not islink(ftpperso) and lexists(ftpperso):
        rmtree(ftpperso)
    create_ftpsymlink()

def gen_groupedir(uid, homedir, shares):
    """
        Gestion du répertoire "groupes"
    """
    groupedir = join(homedir, 'groupes')
    if isdir(groupedir):
        rmtree(groupedir)
    makedirs(groupedir, 0o500)
    chown(groupedir, uid, -1)
    #les ACLs ne sont pas mise
    #system('setfacl -bk %s' % groupedir)
    for share in shares:
        # sinon partage avec lettre de lecteur
        if share['drive'] == "":
            # lien dans le répertoire "groupes"
            symlink(share['path'], join(groupedir, share['name']))
