#!/usr/bin/env python
# -*- coding: utf8 -*-
#
# PEB : */0[2-3]/2013 -> now()
#
# WTFPL

import sys
import psycopg2
import mac_prise
from threading import Thread
import time

sys.path.append('/usr/scripts/gestion')
import annuaires_pg

class ThreadWithReturnValue(Thread):
    """
    Classe de threading qui récupère le "return" d'une fonction, et le renvoie avec
    output()
    """
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs, Verbose)
        self._return = None

    def run(self):
        """
        Méthode appelée par start.
        On la réécrit pour que le retour soit non vide.
        """
        if self._Thread__target is not None:
            self._return = self._Thread__target(*self._Thread__args,
                                                **self._Thread__kwargs)
    def output(self):
        """
        Renvoie la sortie de la fonction threadée.
        """
        Thread.join(self)
        return self._return

def get_curseur(temps):
    """
    Au cas où le nombre max de connexions est atteint.
    """
    i = 0
    while i <= 5:
        try:
            connecteur = psycopg2.connect(database="mac_prises", user="crans")
            connecteur.set_session(autocommit=True)
            break
        except Exception as  e:
            print e
            i += 1
            time.sleep(3)

    if i == 6:
        raise EnvironmentError('Impossible de contacter la base postgresql')
    else:
        return connecteur.cursor()

if __name__ == '__main__':
    """
    On envoie sur n threads les n arguments, puis on récupère les sorties
    et on les enregistre dans une base postgresql
    """
    switches = annuaires_pg.all_switchs()
    date = time.strftime('%F %T')
    threads = {}
    output = {}
    for switch in switches:
        threads[switch] = ThreadWithReturnValue(target=mac_prise.liste_chambres_macs, args=(switch, annuaires_pg))
        threads[switch].start()

    # On change de boucle, car il faut absolument que tous les threads aient démarré, histoire qu'on
    # parallélise vraiment !
    for switch in switches:
        output[switch] = threads[switch].output()
    
    curseur = get_curseur(time.time())

    requete = "INSERT INTO correspondance (date, chambre, mac) VALUES (%s, %s, %s);"

    for switch in output:
        for chambre in output[switch]:
            for mac in output[switch][chambre]:
                curseur.execute(requete, (date, chambre, mac))
