# -*- coding: utf-8 -*-
from configobj import ConfigObj, ParseError
from validate import Validator, ValidateError
import os
import string
from logging import getLogger
from wxUI import commonMessageDialogs
log = getLogger("config_utils")

class ConfigLoadError(Exception): pass

def load_config(config_path, configspec_path=None, copy=True, *args, **kwargs):
    spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True)
    try:
        config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs)
    except ParseError:
        raise ConfigLoadError("Unable to load %r" % config_path)
    validator = Validator()
    validated = config.validate(validator, preserve_errors=False, copy=copy)
    if validated == True:
        config.write()
        return config
    else:
        log.exception("Error in config file: {0}".format(validated,))
        commonMessageDialogs.invalid_configuration()

def is_blank(arg):
    "Check if a line is blank."
    for c in arg:
        if c not in string.whitespace:
            return False
    return True

def get_keys(path):
    "Gets the keys of a configobj config file."
    res=[]
    fin=open(path)
    for line in fin:
        if not is_blank(line):
            res.append(line[0:line.find('=')].strip())
    fin.close()
    return res

def hist(keys):
    "Generates a histogram of an iterable."
    res={}
    for k in keys:
        res[k]=res.setdefault(k,0)+1
    return res

def find_problems(hist):
    "Takes a histogram and returns a list of items occurring more than once."
    res=[]
    for k,v in hist.items():
        if v>1:
            res.append(k)
    return res

def clean_config(path):
    "Cleans a config file. If duplicate values are found, delete all of them and just use the default."
    orig=[]
    cleaned=[]
    fin=open(path)
    for line in fin:
        orig.append(line)
    fin.close()
    for p in find_problems(hist(get_keys(path))):
        for o in orig:
            o.strip()
            if p not in o:
                cleaned.append(o)
    if len(cleaned) != 0:
        cam=open(path,'w')
        for c in cleaned:
            cam.write(c)
        cam.close()
        return True
    else:
        return False
