#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# postdiff.py
# -----------
#
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.

'''Petit utilitaire pour voir les différences de configuration entre deux
fichiers de configurations main.cf de postfix'''

import sys, re, commands

__re_param_separator = re.compile('[ \t]*,[ \t]*|[ \t]+')

def postconf(conf_dir):
    vars = commands.getoutput("/usr/sbin/postconf -n -c %s" % conf_dir).split('\n')[0:-1]
    canonicalized = {}
    for var in vars:
        [varname, params] = var.split(' = ')
        params = __re_param_separator.split(params)
        params.sort()
        canonicalized[varname] = params
    del canonicalized["config_directory"]
    return canonicalized

def compare(a, b):
    common = []
    onlya = []
    onlyb = []
    for var in a:
        if b.has_key(var):
            common.append(var)
        else:
            onlya.append(var)
    for var in b:
        if a.has_key(var):
            if not var in common:
                common.append(var)
        else:
            onlyb.append(var)
    return common, onlya, onlyb

def __usage(err):
    sys.stderr.write("%s\n" % err)
    sys.stderr.write("usage: %s <main.cf_1> <main.cf_2>\n" % os.path.basename(sys.argv[0]))
    sys.exit(2)
    
if __name__ == '__main__':
    import tempfile, os, sys
    sys.path.append('/usr/scripts/gestion')
    from affich_tools import cprint

    if len(sys.argv) != 3:
        __usage("Mauvais nombre d'arguments")

    for i in 1, 2:
        if not os.access(sys.argv[i], os.R_OK):
            __usage("%s n'est pas lisible!" % sys.argv[i])

    conf = {}
    # On copie les fichier car postconf n'accepte qu'un dossier en
    # paramètre et non un fichier directement
    tempd = tempfile.mkdtemp()
    for i in 1, 2:
        open(tempd + "/main.cf", "w").write(file(sys.argv[i]).read())
        conf[i] = postconf(tempd)
    os.unlink(tempd + "/main.cf")
    os.rmdir(tempd)

    diff = compare(conf[1], conf[2])
    diff_common = filter(lambda var: conf[1][var] != conf[2][var], diff[0])
    for i in 0, 1, 2:
        diff[i].sort()
    for i in 1, 2:
        if len(diff[i]) > 0:
            cprint(u"variables définis uniquement dans %s" % sys.argv[i], "bleu")
            for var in diff[i]:
                print " %s = %s" % (var, ", ".join(conf[i][var]))
    if len(diff_common) > 0:
        cprint(u"variables différentes dans a:%s et b:%s" % (sys.argv[1], sys.argv[2]), "bleu")
        for var in diff_common:
            cprint(" a:%s = %s" % (var, ", ".join(conf[1][var])), "gris")
            cprint(" b:%s = %s" % (var, ", ".join(conf[2][var])), "gras")
    if len(diff_common) == 0 and len(diff[1]) == 0 and len(diff[2]) == 0:
        cprint("Les fichiers sont identiques!")

