#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from IPy import IP
from glob import glob
from os import makedirs, unlink
from os.path import join, isdir, isfile
from pyeole.service import service_out
from creole.parsedico import parse_dico
from creole.eosfunc import load_container_var, is_ip
from socket import inet_aton
import struct
import re

dico = parse_dico()
container = load_container_var()

DHCP_DIR = 'etc/dhcp3/fixed-address'
CONFIG_FILE = '/var/lib/eole/config/dhcp.conf'
DHCP_TMPL = "host %s { hardware ethernet %s; fixed-address %s; }\n"

def build_dir_name():
    """
    Calcul du chemin du répertoire en fonction du mode
    conteneur/non conteneur
    """
    return join('/', container['container_path_dhcp'], DHCP_DIR)

def build_file_name(ipbasse, iphaute):
    """
    Calcul du chemin de l'un des fichiers de configuration
    """
    dirname = build_dir_name()
    return join(dirname, ipbasse+"_"+iphaute+'.txt')

def clean():
    """
    remove old files and create empty files
    """
    dirname = build_dir_name()
    if not isdir(dirname):
        makedirs(dirname)
    for name in glob(join(dirname, '*')):
        unlink(name)
    for i in range(0, len(dico['ip_basse_dhcp'])):
        ipbasse = dico['ip_basse_dhcp'][i]
        iphaute = dico['ip_haute_dhcp'][i]
        file_name = build_file_name(ipbasse, iphaute)
        fh = open(file_name, 'w+')
        fh.write('')
        fh.close()

def gen_dhcp_config(tupples_fixed_address):
    """
    Génération de la configuration
    """
    names = []
    mac_addrs = []
    ip_addrs = []
    for name, ip, mac in tupples_fixed_address:
        subnet_found = False
        if name in names:
            print "Le nom {0} est déjà présent".format(name)
            continue
        names.append(name)

	if not re.match("[0-9a-f]{2}([-:][0-9a-f]{2}){5}$", mac.lower()):
            print "L'adresse MAC {0} n'est pas une adresse valide".format(mac)
            continue
        if mac in mac_addrs:
            print "L'adresse MAC {0} est déjà présente".format(mac)
            continue
        mac_addrs.append(mac)
        if not is_ip(ip):
            print "L'adresse IP {0} n'est pas une adresse valide".format(ip)
            continue
        if ip in ip_addrs:
            print "L'adresse IP {0} est déjà présente".format(ip)
            continue
        ip_addrs.append(ip)
        for i in range(0, len(dico['ip_basse_dhcp'])):
            ipbasse = dico['ip_basse_dhcp'][i]
            iphaute = dico['ip_haute_dhcp'][i]
            ipbasse_test = ip2long(ipbasse)
            iphaute_test = ip2long(iphaute)
            ip_test = ip2long(ip)
            file_name = build_file_name(ipbasse, iphaute)
            if ipbasse_test <= ip_test and ip_test <= iphaute_test:
                fh = open(file_name, 'a')
                fh.write(DHCP_TMPL % (name, mac, ip))
                fh.close()
                subnet_found = True
                break
        if not subnet_found:
            print "Le poste {1} ({0}) n'est pas dans une plage d'adresses déclarée".format(ip, name)

def read_ead_config():
    """
    lecture des adresses configurées dans l'EAD
    """
    tupples_fixed_address = []
    if isfile(CONFIG_FILE):
        for line in file(CONFIG_FILE).read().splitlines():
            if line.count('#') == 2:
                tupples_fixed_address.append(line.split('#'))
    return tupples_fixed_address

def ip2long(ip):
    packed = inet_aton(ip)
    lng = struct.unpack("!L", packed)[0]
    return lng

if __name__ == '__main__':
    clean()
    gen_dhcp_config(read_ead_config())
    if len(sys.argv) == 1:
        # si aucun argument, on redémarre le service
        res = service_out('dhcp3-server', 'restart', 'dhcp')
        if res[0] != 0:
            print res[2].rstrip()
