#!/usr/bin/env python

import os.path
import sys
from copy import copy
from string import strip

config_directory = "/var/cache/debconf"
#config_directory = "."

def add_d2(*args):
    """ 1st arg: top-level.
        [... keyname for dictionary ...]
        [... keyname for dictionary ...]
        [... keyname for dictionary ...]
        final arg: value.
    """

    args = list(args)
    firstdict = args[0]
    key_names = list(args[1:-2])
    final_key_name = args[-2]
    val = args[-1]

    next_dict = firstdict
    dict_list = []
    for keyname in key_names:
        next_dict = next_dict.setdefault(keyname, {})
        dict_list.append(next_dict)

    if not dict_list:
        dict_list = [firstdict]

    dict_list[-1][final_key_name] = val
    key_names.reverse()

def dict_list_add(into_dict, table1, table2):
    d  = into_dict.get(table1, [])
    d.append(table2)
    into_dict[table1] = d

def add_to_dict(dd, key1, key2, val):
    d  = dd.get(key1, {})
    d[key2] = val
    dd[key1] = d

def add_dict_to_dict_to_dict(dd, key1, key2, key3, val):
    """ whoa. way cool.
    """
    return add_d2(dd, key1, key2, key3, val)
    d1 = dd.get(key1, {})
    d2 = d1.get(key2, {})
    d2[key3] = val
    d1.setdefault(key2, d2)
    dd.setdefault(key1, d1)

def add_dict_to_dict(dd, key1, key2, val):
    d = dd.get(key1, {})
    d[key2] = val
    dd.setdefault(key1, d)

def split_find(txt, split_by=':'):
    txt = txt.strip()
    index = txt.find(split_by) # ignore -1.  assume database ok (!)
    return txt[:index].strip(), txt[index+1:].strip()

CODES = ['Description', 'Extended_description']

class debconf_db:

    def __init__(self):

        self.db = {}
        self.langs = {} # slowly collates a list of languages
        self.property_names = {}

    def add_items(self, package_name, module_parm, res):

        for key_name, val in res.items():
            is_a_code_name = 0
            #print 'key, val', repr(key_name), repr(module_parm), repr(val)
            for code_name in CODES:
                if key_name.startswith(code_name+'-'):
                    #print 'iscodename:', repr(key_name), repr(code_name)
                    is_a_code_name = code_name
                    break

            if not is_a_code_name:
                #print 'notcodename:', package_name, repr(key_name), repr(code_name), module_parm
                #(package_name, module_param) = split_find(val, '/')
                add_d2(self.db, package_name, module_parm, key_name, val)
            else:
                #print 'codename:', repr(key_name), repr(code_name)
                (description_keyword, lang_code) = split_find(key_name, '-')
                dict_list_add(self.langs, lang_code, None) # collate language list
                self.property_names[code_name] = None
                add_to_db = getattr(self, code_name, {})
                #print 'debug', code_name, repr(package_name), repr(key_name), repr(module_parm), repr(lang_code), repr(val)
                add_d2(add_to_db, package_name, module_parm, code_name, lang_code, val)
                setattr(self, code_name, add_to_db)


    def process_lines_into_db(self, section):

        res = {}
        for l in section:
            (key_name, the_rest) = split_find(l)

            res[key_name] = the_rest
            if key_name == 'Name':
                (package_name, module_param) = split_find(the_rest, '/')
                #print 'keyname, therest pkg mod', key_name, the_rest, package_name, module_param

                #print 'pkgname', repr(package_name), repr(key_name)
            self.add_items(package_name, module_param, res)

    def read_database_into_dict(self, fname):

        fname = os.path.join(config_directory, fname)

        so_far = []

        for l in open(fname, "r").readlines():
            l = l.strip()
            if len(l):
                so_far.append(l)
                continue
            self.process_lines_into_db(so_far)
            so_far = []

    def get_description(self, package_name, param_name=None, languages=None):
        """
            if you want no languages (why???) set languages=[]
        """

        if languages is None: # means 'select all languages'
            languages = copy(self.langs)
        if isinstance(languages, type({})):
            languages = languages.keys()
        if not isinstance(languages, type([])):
            languages = [languages]

        res = {}

        #print 'dbkeys', dir(self), self.property_names.keys()
        for code_name in CODES:
            getdb = getattr(self, code_name, {})
            if not getdb:
                continue
            #print 'package_name', package_name, getdb.keys()
            pkg = getdb.get(package_name, {})
            #print 'param_name', param_name, getdb.keys()
            pkg = pkg.get(param_name, {})
            #print 'keys', param_name, pkg.keys()
            for lang_name in languages:
                param_attr_name = "%s-%s" % (code_name, lang_name)
                param_attr_name = lang_name
                params = pkg.get(param_attr_name, {})
                #print 'params', code_name, repr(params)
                if params:
                    add_d2(res, lang_name, params)

        return res


    def print_out_db(self):

        package_names = self.db.keys()
        package_names.sort()

        print 'packages:'
        print '\n'.join(package_names)

        for package_name in package_names:
            module_params = self.db[package_name]
            module_param_names = module_params.keys()
            module_param_names.sort()

            #print '%s:' % package_name, module_param_names

            for param_name in module_param_names:

                params = module_params[param_name]

                print '\t%s / %s' % (package_name, param_name)

                attrib_names = params.keys()
                attrib_names.sort() # better order than alphabetical

                for attrib_name in attrib_names:

                    attribs = params[attrib_name]

                    #print '\t\t%s: %s' % (attrib_name, repr(attribs))

                    is_a_codename = 0
                    for code_name in CODES:
                        if attrib_name.startswith(code_name):
                            is_a_codename = 1
                    if not is_a_codename:
                        print '\t\t%s: %s' % (attrib_name, attribs)
                        continue

                    first_title = 1

                    for code_name in CODES:
                        if not attrib_name.startswith(code_name):
                            continue

                        desc = self.get_description(package_name, param_name, attrib_name)

                        #print 'desc:', desc
                        if not desc.has_key(code_name):
                            continue

                        if first_title:
                            print '\t%s: %s' % (attrib_name, attribs)
                            first_title = 0

                        for (k, v) in desc[code_name].items():
                            sys.stdout.write('\t\t%s:' % k)
                            text = v.strip().split('\\n')
                            for l in text:
                                sys.stdout.write('\t%s\n' % str(l)) # iso-8859-15?
                        sys.stdout.write('\n')

def test():

    db = debconf_db()
    #db.read_database_into_dict("test_data.dat")
    db.read_database_into_dict("templates.dat")
    db.read_database_into_dict("templates.dat")
    db.print_out_db()

if __name__ == '__main__':
    test()

