#! /usr/bin/env python
# -*- coding: utf-8 -*-

'''Ce script permet de savoir s'il y a du monde à la kfet, filtre par membres actifs.'''

import sys
from socket import gethostname
import collections

if gethostname() != "zamok":
    print "Merci d'executer ce script sur zamok."
    sys.exit(1)

sys.path.append('/usr/scripts/gestion')
from ldap_crans import crans_ldap
from hptools import hpswitch, ConversationError
from affich_tools import coul, cprint
from whos import aff
from os import system
import xml.dom.minidom

def get_wifi_connected_client(host):
    u""" Renvoie la liste des clients, pour une borne wifi donnée.
    N'est plus vraiment utilisée car les bornes sont de toutes façon
    connectées au switch (backbone en fait)"""
    f = open('/usr/scripts/var/wifi_xml/%s.xml' % host,'r')
    doc = xml.dom.minidom.parse(f)
    f.close()
    return [ mac.firstChild.nodeValue for mac in doc.getElementsByTagName('mac') ]

# L'ordre est important : il détermine comment sont empilés les valeurs
# dans le graphe (mode STACK). Les premières valeurs ont donc intérêts
# à avoir le moins de variations (empilées les premières)
STATE_DESCR = collections.OrderedDict([
        ('unknown_macs', ('machines inconnues de la base', 0xff0000)),
        ('crans', ('machines du crans', 0x0000ff)),
        ('ma', ('machines de membres actifs', 0x00ff00)),
        ('adh', ('autres machines appartenant aux autres adhérents', 0xe5ff00)),
])
def get_state():
    sw = hpswitch('backbone.adm.crans.org')
    db = crans_ldap()
    res = {'ma': [],
        'crans': [],
        'adh': [],
        'bde': [],
        'unknown_macs': [],
        'ttyfound': 0,
     }
    try:
        macs = sw.show_prise_mac(21) #Devine quoi, c'est la prise de la kfet
    except ConversationError:
        cprint("Impossible de communiquer avec le switch !", 'rouge')
        return
    if macs:
        for mac in macs:
            fm = db.search("mac=%s" % mac)
            if fm['machine']:
                m = fm['machine'][0]
                if fm['machineCrans'] or fm["borneWifi"]:
                    key = 'crans'
                elif hasattr(m.proprietaire(),'droits') and m.proprietaire().droits():
                    key = 'ma'
                elif m.proprietaire().idn == "cid" and m.proprietaire().id() == "1":
                    key = 'bde'
                else:
                    key = 'adh'
                res[key].append(m)
            else:
                res['unknown_macs'].append(mac)
    return res

def summary(current, show_all=False):
    u"""Réalise un joli aperçu de l'état donné en paramètre."""
    if current['ma']:
        cprint('---=== Machines des membres actifs ===---', 'bleu')
        aff(current['ma'])
        cprint("---=== Il y a du monde à la Kfet ! ===---", 'vert')
    else:
        cprint("---=== Il semble n'y avoir personne à la Kfet ... ===---", 'rouge')
    for mac in current['unknown_macs']:
        cprint("Machine inconnue: %s" % mac, 'rouge')
    if show_all:
        if current['crans']:
            cprint("---=== Machines Cr@ns ===---", 'bleu')
            aff(current['crans'])
        if current['bde']:
            cprint("---=== Machines du BDE ===---", 'bleu')
            aff(current['bde'])
        if current['adh']:
            cprint("---=== Machines d'adhérents ===---", 'bleu')
            aff(current['adh'])
    
def munin_config():
    """Donne la configuration du graphe munin"""
    print """graph_title Membres actifs à la kfet
graph_vlabel N
graph_category environnement"""

    for (name,(descr,color)) in STATE_DESCR.iteritems():
        print """%(name)s.label %(descr)s
%(name)s.draw AREASTACK
%(name)s.colour %(color)06X""" % {'name': name, 'descr': descr, 'color': color}
    # Dans le doute, n'affichons pas les adhérents
    print "adh.graph no"

def munin(current):
    """S'occupe de l'affichage pour munin. TODO: l'écrire."""
    for name in STATE_DESCR.iterkeys():
        print """%(name)s.value %(value)s""" % {'name': name, 'value': len(current[name])}

if __name__ == '__main__':
    # Si on veut afficher aussi les machines qui sont normalement masquées
    really = "--really" in sys.argv or "--all" in sys.argv
    if really:
        # Par contre, ça n'est accessible qu'aux nounous
        db = crans_ldap()
        really = u'Nounou' in db.getProprio(db.cur_user).droits()
        if not really:
            cprint("Vous n'avez pas les droits requis, --really ignoré.", 'jaune')
    state = get_state()
    summary(state, show_all=really)
