import collections
import six


def parseColumnDefs(defs, keyOrder=None):
    """
    Translate a few different forms of column definitions into a single common format.
    These formats are accepted for all methods which request column definitions (createTable,
    checkTable, etc)
        list of tuples:  [(name, type, <constraints>), ...]
        dict of strings: {name: type, ...}
        dict of tuples:  {name: (type, <constraints>), ...}
        dict of dicts:   {name: {'Type': type, ...}, ...}
        
    Returns dict of dicts as the common format.
    """
    if keyOrder is None:
        keyOrder = ['Type', 'Constraints']
    def isSequence(x):
        return isinstance(x, list) or isinstance(x, tuple)
    def toDict(args):
        d = collections.OrderedDict()
        for i,v in enumerate(args):
            d[keyOrder[i]] = v
            if i >= len(keyOrder) - 1:
                break
        return d
        
    if isSequence(defs) and all(map(isSequence, defs)):
        return collections.OrderedDict([(c[0], toDict(c[1:])) for c in defs])
        
    if isinstance(defs, dict):
        ret = collections.OrderedDict()
        for k, v in defs.items():
            if isSequence(v):
                ret[k] = toDict(v)
            elif isinstance(v, dict):
                ret[k] = v
            elif isinstance(v, six.string_types):
                ret[k] = {'Type': v}
            else:
                raise Exception("Invalid column-list specification: %s" % str(defs))
        return ret
        
    else:
        raise Exception("Invalid column-list specification: %s" % str(defs))