# -*- coding: utf-8 -*-
###########################################################################
# Eole NG - 2009
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
###########################################################################
"""
    librairie de gestion des comptes 'Responsables'
"""
from scribe.eoleuser import User, gen_common_attrs, send_first_mail
from scribe.eoletools import to_list, format_current_date, not_empty, \
replace_cars
from pyeole.ssha import ssha_encode
from ldap import MOD_REPLACE, MOD_ADD
from scribe.ldapconf import USER_DN, MAIL_DOMAIN, RESPONSABLE_FILTER
from scribe.eleves import Eleve

def gen_adresse_attrs(**args):
    """
    Gestion des attributs responsables
    """
    attrs = []
    attributs = [('ENTPersonAdresse', 'adresse'),
                 ('ENTPersonCodePostal', 'code'),
                 ('ENTPersonVille', 'ville'),
                 ('ENTPersonPays', 'pays'),
                 ('homePhone', 'telephone'),
                 ('telephoneNumber', 'tel_pro'),
                 ('mobile', 'tel_portable'),
    ]
    for att, cle in attributs:
        if not_empty(args, cle):
            attrs.append((MOD_REPLACE, att, args[cle]))
    return attrs

class Responsable(User):
    """
        classe pour la gestion des responsables élèves Scribe
    """
    _type = 'responsables'
    profil = 'responsable'
    filtre = "(&%s)" % RESPONSABLE_FILTER
    must_args = ['login', 'password', 'nom', 'prenom', 'eleve']
    may_args = dict(mail='restreint', civilite='', date='',
                    adresse='', code='', ville='', pays='',
                    telephone='', tel_pro='', tel_portable='',
                    int_id='', entlogin=True, mailperso='',
                    entpersonjointure='',
                )

    has_samba = False
    has_ftp = False

    def _add_scribe_user(self, login, **args):
        """
            Création du Responsable
        """
        mail = args['mail']
        if '@' not in mail:
            if mail in ['internet', 'restreint']:
                mail = "{0}@{1}".format(login, MAIL_DOMAIN[mail])
                maildir = self.get_maildir(login)
            else:
                mail = ''
                maildir = ''
        else:
            maildir = ''
        eleves_dn = []
        args['eleve'] = to_list(args['eleve'])
        for eleve_entry in args['eleve']:
            eleves_dn.append(USER_DN % dict(uid=eleve_entry, _type='eleves'))
        # on crée d'abord l'objet 'inetOrgPerson'
        # puis on le met à jour ;)
        user_dn = USER_DN % dict(uid=login, _type=self._type)
        userpassword = ssha_encode(args['password'])
        datas = [(('objectClass', 'inetOrgPerson'))]
        datas.append(('uid', login))
        datas.append(('cn', "%(prenom)s %(nom)s" % args ))
        datas.append(('sn', args['nom']))
        datas.append(('userPassword', userpassword))
        datas.append(('displayName', "%(prenom)s %(nom)s" % args ))
        datas.append(('givenName', args['prenom'] ))
        self.ldap_admin._add(user_dn, datas)
        # le reste
        datas = []
        objectclass = self._get_attr(login, 'objectClass')
        objectclass.extend(['responsable', 'ENTPerson', 'ENTAuxPersRelEleve'])
        datas.append((MOD_REPLACE, 'objectClass', objectclass))
        datas.extend(gen_common_attrs(login, entprofil=self.profil, **args))
        datas.append((MOD_REPLACE, 'ENTAuxPersRelEleveEleve', eleves_dn))
        datas.append((MOD_REPLACE, 'eleve', args['eleve']))
        datas.append((MOD_REPLACE, 'sambaLMPassword', 'x' ))
        datas.append((MOD_REPLACE, 'sambaNTPassword', 'x' ))
        if not_empty(args, 'mailperso'):
            datas.append((MOD_REPLACE, 'mailPerso', args['mailperso']))
        if mail != '':
            datas.append((MOD_REPLACE, 'mail', mail))
        if maildir != '':
            datas.append((MOD_REPLACE, 'mailHost', 'localhost'))
            datas.append((MOD_REPLACE, 'mailDir', maildir))
        datas.extend(gen_adresse_attrs(**args))
        self.ldap_admin._modify(user_dn, datas)
        if maildir != '':
            send_first_mail(mail)

    def _add_perso(self, login, **args):
        """
            pas de dossier
        """
        pass

    def _update(self, login, eleve, **args):
        """
            Mise à niveau via l'extraction
        """
        user_dn = USER_DN % dict(uid=login, _type=self._type)
        # mise à jour adresse, numéros de téléphone et mail
        datas = gen_adresse_attrs(**args)
        if not_empty(args, 'int_id'):
            datas.append((MOD_REPLACE, 'intid', args['int_id'] ))
        if not_empty(args, 'mailperso'):
            datas.append((MOD_REPLACE, 'mailPerso', args['mailperso'] ))
        if not_empty(args, 'entpersonjointure'):
            datas.append((MOD_REPLACE, 'ENTPersonJointure', args['entpersonjointure']))
        datas.append((MOD_REPLACE, 'sn', args['nom']))
        datas.append((MOD_REPLACE, 'givenName', args['prenom']))
        datas.append((MOD_REPLACE, 'cn', "%(prenom)s %(nom)s" % args ))
        datas.append((MOD_REPLACE, 'displayName', "%(prenom)s %(nom)s" % args ))
        datas.append((MOD_REPLACE, 'gecos', replace_cars("%(prenom)s %(nom)s" % args) ))
        datas.append((MOD_REPLACE, 'LastUpdate', format_current_date()))
        # vérification des élèves du responsable
        old_eleves = self._get_attr(login, 'ENTAuxPersRelEleveEleve')
        eleve = to_list(eleve)
        for eleve_uid in eleve:
            entry = USER_DN % dict(uid=eleve_uid, _type='eleves')
            if entry not in old_eleves:
                #print "ajout élève %s" % entry
                datas.append((MOD_ADD, 'ENTAuxPersRelEleveEleve', entry))
                datas.append((MOD_ADD, 'eleve', eleve_uid))
            else:
                #print "élève %s : OK" % entry
                pass
        self.ldap_admin._modify(user_dn, datas)

    def _get_responsables(self, attrs=['uid'], eleve=''):
        """
        Renvoie la liste des responsables
        """
        if eleve != '':
            filtre = "(&%s(eleve=%s))" % (self.filtre, eleve)
        else:
            filtre = self.filtre
        return self._get_users(filtre=filtre, attrs=attrs)

    def c_del_association(self, login, eleves):
        """
        suppression d'une association élève-responsable
        """
        user_dn = USER_DN % dict(uid=login, _type=self._type)
        # vérification des élèves du responsable
        buf_ent_eleves = self._get_attr(login, 'ENTAuxPersRelEleveEleve')
        buf_eleves = self._get_attr(login, 'eleve')
        eleves = to_list(eleves)
        mod = False
        for eleve_uid in eleves:
            entry = USER_DN % dict(uid=eleve_uid, _type='eleves')
            if entry in buf_ent_eleves:
                buf_ent_eleves.remove(entry)
                mod = True
            if eleve_uid in buf_eleves:
                buf_eleves.remove(eleve_uid)
        if not buf_ent_eleves or not buf_eleves:
            raise Exception("Un responsable doit être associé à au moins un élève")
        if mod:
            datas = []
            datas.append((MOD_REPLACE, 'ENTAuxPersRelEleveEleve', buf_ent_eleves))
            datas.append((MOD_REPLACE, 'eleve', buf_eleves))
            self.ldap_admin._modify(user_dn, datas)

    def c_add_association(self, login, eleves):
        """
        ajout d'une association élève-responsable
        """
        user_dn = USER_DN % dict(uid=login, _type=self._type)
        # vérification des élèves du responsable
        buf_ent_eleves = self._get_attr(login, 'ENTAuxPersRelEleveEleve')
        buf_eleves = self._get_attr(login, 'eleve')
        eleves = to_list(eleves)
        mod = False
        ldapeleve = Eleve()
        ldapeleve.ldap_admin = self.ldap_admin
        for eleve_uid in eleves:
            if not ldapeleve._is_eleve(eleve_uid):
                raise Exception("Aucun élève ne possède le login %s" % eleve_uid)
            entry = USER_DN % dict(uid=eleve_uid, _type='eleves')
            if entry not in buf_ent_eleves:
                buf_ent_eleves.append(entry)
                mod = True
            if eleve_uid not in buf_eleves:
                buf_eleves.append(eleve_uid)
        if mod:
            datas = []
            datas.append((MOD_REPLACE, 'ENTAuxPersRelEleveEleve', buf_ent_eleves))
            datas.append((MOD_REPLACE, 'eleve', buf_eleves))
            self.ldap_admin._modify(user_dn, datas)

