#!/usr/bin/env python3
#-*-coding:utf-8-*-
###########################################################################
#
# Eole NG - 2009
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html
# eole@ac-dijon.fr
#
###########################################################################

"""
Utilitaire de gestion des groupes spéciaux
"""

import sys, getopt
from os.path import basename
from scribe.eoleshare import Share, EOLE_SHARES

class specialShares:
    """
    classe de gestion des partages spéciaux
    """

    def test_drive(self, drive):
        """
        Teste la validité syntaxique d'une lettre de lecteur
        """
        if not drive.endswith(":"):
            if len(drive) > 1:
                print('Lettre de lecteur non valide "%s"' % drive)
                sys.exit()
            drive += ':'
        else:
            if len(drive) > 2:
                print('Lettre de lecteur non valide "%s"' % drive)
                sys.exit()
        return drive.upper()

    def verif_drive(self, drive):
        """
        Vérifie si la lettre n'est pas déjà réservée
        """
        drive = self.test_drive(drive)
        share = self.get_share(drive)
        if share != '':
            sharename = share.split()[1]
            print('"%s" est déjà attribuée au partage "%s"' % (drive, sharename))
            sys.exit()

    def verif_share(self, share):
        """
        Vérifie si le partage est modifiable
        """
        if share in EOLE_SHARES:
            print('"%s" est un partage Eole non modifiable' % share)
            sys.exit()

    def add_special_share(self, sharename, drive):
        """
        Fonction d'ajout/modification d'un partage spécial
        """
        drive = self.test_drive(drive)
        self.verif_drive(drive)
        self.verif_share(sharename)
        print('Réservation de la lettre de lecteur "%s" pour le partage "%s"' % (drive, sharename))
        ldapshare = Share()
        ldapshare.ldap_admin.connect()
        ldapshare._set_share_drive(sharename, drive)
        ldapshare.ldap_admin.close()

    def del_special_share(self, sharename):
        """
        Fonction de suppression de la lettre réservée d'un partage spécial
        """
        self.verif_share(sharename)
        ldapshare = Share()
        if ldapshare.get_letter(sharename) != '':
            print('Désactivation de la réservation de lettre pour le partage "%s"' % sharename)
            ldapshare.ldap_admin.connect()
            ldapshare._set_share_drive(sharename)
            ldapshare.ldap_admin.close()
        else:
            print("""Aucune lettre n'était associé au partage "%s" """ % sharename)

    def get_letter(self, sharename):
        """
        Fonction retournant la lettre associée à un partage spécial
        (ou "" si pas de lettre)
        """
        ldapshare = Share()
        letter = ldapshare.get_letter(sharename)
        if letter != '':
            return '%s %s'% (letter, sharename)
        else:
            return ''

    def get_share(self, drive):
        """
        Retourne le partage associé à "drive" si existant, "" sinon
        """
        ldapshare = Share()
        lettre_dict = ldapshare.get_reserved_letters()
        drive = self.test_drive(drive)
        for share in list(lettre_dict.keys()):
            if lettre_dict[share] == drive:
                return '%s %s' % (drive, share)
        return ''

# FIXME
#    def get_shares(self):
#        """Fonction de lecture des partages reliés à un *groupe*
#        """
#        try:
#            reload(backend_conf)
#            query=ldap.open(backend_conf.serveur)
#            query.simple_bind_s("cn=admin, o=gouv, c=fr", backend_conf.ldap_passwd)
#            result_shares=query.search_s("o=gouv, c=fr", ldap.SCOPE_SUBTREE, \
#            "(objectClass=sambaFileShare)")
#            query.unbind()
#        except:
#            print 'Erreur connexion LDAP, Abandon !'
#            sys.exit()
#
#        dico_shares={}
#        for share in result_shares:
#            dico_shares[share[1]['sambaShareName'][0]]=share[1]['sambaShareGroup'][0]
#        return dico_shares

    def print_shares(self):
        """
        fonction d'affichage de tous les partages spéciaux
        """
        ldapshare = Share()
        special_shares = ldapshare.get_reserved_letters()
        shares = list(special_shares.keys())
        shares.sort()
        for share in shares:
            if share in EOLE_SHARES:
                print('%s %s (réservée Eole)' % (special_shares[share], share))
            else:
                print('%s %s' % (special_shares[share], share))

# FIXME
#    def get_reserved_letters(self):
#        """Fonction retournant les partages pour backend Ead2
#        """
#        d = {}
#        shares_list = self.get_shares().keys()
#        reload(shares)
#        for share in shares_list:
#            if shares.eole_shares.has_key(share):
#                lettre = shares.eole_shares[share]
#                d[share] = lettre
#            elif shares.special_shares.has_key(share):
#                lettre = shares.special_shares[share]
#                d[share] = lettre
#            else:
#                d[share] = ''
#        d['perso'] = 'U:'
#        return d

def main():
    """
    Boucle principale
    """
    # définition du message d'aide
    help_msg ="""arguments:
         -p (--partage) nom du partage
         -l (--lettre) lettre sur laquelle connecter le partage sous windows
         -h (--help) (ce message)

     exemples :

     * ajout/modification de la lettre de partage      : %(app)s -p partage -l J:
     * suppression de la lettre réservée               : %(app)s -p partage -l ""
     * récupération de la lettre associée à un partage : %(app)s -p partage
     * récupération du partage associé à une lettre    : %(app)s -l J:
     * récupération de la liste des partage spéciaux   : %(app)s

     """ % dict(app = basename(sys.argv[0]))

    # récupération des arguments de la ligne de commande
    try:
        options, args = getopt.getopt(sys.argv[1:], 'p:l:h',
                                 ['partage=',
                                  'lettre=',
                                  'help'])
    except getopt.GetoptError:
        # on récupère les information de l'exception
        er_type, er_value, er_traceback = sys.exc_info()
        er_msg = str(er_value)
        # on prévient l'utilisateur que l'option nécessite un argument
        sys.exit("l'option -%s est inconnue ou nécessite un argument" % \
                 er_msg[er_msg.index('-')+1])

    partage = None
    letter = None
    sp_share = specialShares()

    for (opt, val) in options:
        if (opt == '-p') or (opt == '--partage'):
            partage = val
        elif (opt == '-l') or (opt == '--lettre'):
            letter = val
        elif (opt == '-h') or (opt == '--help'):
            sys.exit(help_msg)

    # sans arguments => affichage
    if partage is None:
        if letter is None:
            sys.exit(sp_share.print_shares())
        else:
            sys.exit(sp_share.get_share(letter))
    else:
        if letter is None:
            sys.exit(sp_share.get_letter(partage))
        elif letter == '':
            sys.exit(sp_share.del_special_share(partage))
        else:
            sys.exit(sp_share.add_special_share(partage, letter))

# si appelé en ligne de commande...
if __name__ == '__main__':
    main()

