#!/usr/bin/env python
# -*- coding: UTF-8 -*-
###########################################################################
# Eole NG - 2007
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
###########################################################################

HELP = """

usage: aaf_lit_csv.py [options] <nom_fichier.csv>

Ce script permet de prendre en compte un fichier CSV généré par aaf_gen_csv.py
Après lecture du fichier passé en paramètre,

L'adresse du serveur Zéphir est déterminée automatiquement si ce script
est lancé depuis un serveur client enregistré

options:

-c (--check-only)
    effectue la validation des données sans faire l'envoi réel sur zéphir

-n (--no-validate)
    ne pas effectuer de validation pour chaque ligne prise en compte

-d (--delete)
    supprime les associations liées aux fichiers référencés dans le fichier csv

"""

# adresse par défaut si on n'est pas sur un serveur client enregistré
zephir_default = 'localhost'

import getpass, sys, os
try:
    # si disponible, on utilise la librairie modifiée du client Zéphir
    # (n'affiche pas les mots de passe dans l'url en cas de traceback)
    from zephir.eolerpclib import xmlrpclib
except:
    import xmlrpclib

def valid_serveur(serveur, fichier, libelle_serveur, libelle_etab):
    print ("\n- Association du fichier %s avec le serveur %s (%s / %s)" % (fichier, serveur, libelle_serveur, libelle_etab))
    resp = raw_input("  (<entrée> pour valider, <n>/<non> pour rejeter, ou saisir un nouveau nom de fichier) :")
    if resp == "":
        return True, serveur, fichier
    elif resp.lower() in ["n", "non"]:
        return False, serveur, fichier
    else:
        return True, serveur, resp

def valid_fichier(fichier):
    resp = raw_input("\n- Supression de l'association liée au fichier %s ? (<n>/<non> pour annuler) :" % fichier)
    if resp.lower in ['n', 'non']:
        return False
    return True

def associe_serveurs(zephir_proxy, liste_asso, validation=True, send=True):

    serveurs_ok = []
    serveurs_nok = []
    serveurs_echec = []
    for serveur, fichier, libelle_serveur, libelle_etab in liste_asso:
        serv_ok = True
        if validation:
            serv_ok, serveur, fichier = valid_serveur(serveur, fichier, libelle_serveur, libelle_etab)
        if serv_ok:
            if send:
                # appel à Zéphir pour prise en compte du fichier
                try:
                    print "** Appel à zephir.aaf.add_file(%d, %s)"  % (int(serveur), fichier)
                    #rc, result = zephir_proxy.aaf.add_file(int(serveur), fichier)
                    rc, result = zephir_proxy.serveurs.get_serveur(int(serveur))
                    assert rc == 1
                except:
                    import traceback
                    traceback.print_exc()
                    print "  -> Erreur lors de la prise en compte par Zéphir (%d, %s)" % (int(serveur), fichier)
                    serveurs_echec.append('%s|%s|%s|%s' % (serveur, fichier, libelle_serveur, libelle_etab))
                    continue
            serveurs_ok.append('%s|%s|%s|%s' % (serveur, fichier, libelle_serveur, libelle_etab))
        else:
            serveurs_nok.append('%s|%s|%s|%s' % (serveur, fichier, libelle_serveur, libelle_etab))
    return serveurs_ok, serveurs_nok, serveurs_echec

def delete_fichiers(zephir_proxy, liste_asso, validation=True, send=True):
    for serveur, fichier, libelle_serveur, libelle_etab in liste_asso:
        if validation:
            del_ok = valid_fichier(fichier)
            if send:
                print "appel à zephir.aaf.del_file(%s)"  % (fichier)
                #rc, result = zephir_proxy.aaf.del_file(fichier)
                rc, result = zephir_proxy.serveurs.get_serveur(serveur)
                if rc == 1:
                    print "  -> Association supprimée pour le fichier %s" % fichier
                else:
                    print "  -> Erreur lors de la suppression de l'association liée au fichier %s" % fichier
            else:
                print "  -> Association non supprimée pour le fichier %s (mode check-only)" % fichier

def lecture_fichier(nom_fichier):
    f_csv = open(nom_fichier)
    data = f_csv.read().strip().split('\n')
    f_csv.close()
    try:
        liste_asso = []
        for ligne in data:
            serveur, fichier, libelle_serveur, libelle_etab = ligne.split('|')
            liste_asso.append([serveur, fichier, libelle_serveur, libelle_etab])
    except:
        sys.exit("Format invalide : %s" % ligne)
    return liste_asso

def sauve_liste(nom_fichier, liste, commentaire):
    try:
        f = open(nom_fichier, 'w')
        f.write("\n".join(liste))
        f.close()
        print "Fichier %s sauvegardé (%s)\n" % (nom_fichier, commentaire)
    except:
        import traceback
        traceback.print_exc()
        print "! Erreur à l'écriture du fichier %s !\n" % nom_fichier

if __name__ == '__main__':

    validation = True
    send = True
    mode = "ajout"
    # affichage aide
    if '-h' in sys.argv or '--help' in sys.argv:
        print HELP
        sys.exit(0)
    if "-d" in sys.argv or "--delete" in sys.argv:
        mode = "suppression"
    if "-n" in sys.argv or "--no-validate" in sys.argv:
        validation = False
    if "-c" in sys.argv or "--check-only" in sys.argv:
        send = False

    if send:
        try:
            from zephir.zephir_conf.zephir_conf import adresse_zephir
        except:
            saisie = raw_input("Entrez l'adresse du serveur Zéphir (%s si rien):" % zephir_default)
            adresse_zephir = saisie or zephir_default
        # proxy xmlrpc
        user = raw_input("nom de l'utilisateur zephir :")
        pwd = getpass.getpass("mot de passe                :")
        print ""

        if adresse_zephir == 'localhost':
            zephir_proxy = xmlrpclib.ServerProxy('http://%s:%s@localhost:7081' % (user, pwd))
        else:
            zephir_proxy = xmlrpclib.ServerProxy('https://%s:%s@%s:7080' % (user, pwd, adresse_zephir))
    else:
        zephir_proxy = None

    nom_fichier = sys.argv[-1]
    if not os.path.isfile(nom_fichier):
        sys.exit("Erreur, le fichier spécifié n'est pas valide ou non accessible (%s)" % nom_fichier)
    liste_asso = lecture_fichier(nom_fichier)
    if mode == "suppression":
        delete_fichiers(zephir_proxy, liste_asso, validation, send)
    else:
        serveurs_ok, serveurs_nok, serveurs_echec = associe_serveurs(zephir_proxy, liste_asso, validation, send)
        # sauvegarde des fichiers en prenant compte des validations manuelles
        nom_base = os.path.splitext(os.path.basename(nom_fichier))[0]
        print ""
        if serveurs_ok != []:
            msg_send = ""
            if send:
                msg_send = " et prises en compte par Zéphir"
            sauve_liste('%s_ok.csv' % nom_base, serveurs_ok, "associations validées%s" % msg_send)
        if serveurs_nok != []:
            sauve_liste('%s_invalide.csv' % nom_base, serveurs_nok, "association rejetées à la validation")
        if serveurs_echec != []:
            sauve_liste('%s_echec.csv' % nom_base, serveurs_echec, "associations ayant échoué à l'envoi sur Zéphir")
