from logging import warning, debug, critical
from Event import Event
import Utils

def _asLdap(value):
    if isinstance(value, bool):
        if value:
            return ['TRUE']
        else:
            return ['FALSE']
    else:
        return value
        
OP_CREATE = 1
OP_MODIFY = 2
OP_RENAME = 3
OP_DELETE = 4

class Change(object):
    def __init__(self, op, path, new = None, old = None):
        self.op = op
        self.path = path
        self.new = new
        self.old = old

    def __str__(self):
        return '(%s, %s, %s, %s)' % (self.op, self.path, self.new, self.old)

class ChangeSet(object):
    """
    Describes a change set to be applied to configuration.
    """

    def __init__(self):
        self.clear()

    def isEmpty(self):
        return not len(self.changes)
    
    def clear(self):
        """Clear changeset."""
        self.changes = {}
        
    def add(self, dn, op, new = None, old = None):
        # print "adding change (op=%s dn=%s, new=%s, old=%s)" % (op, dn, new, old)
        if op == OP_DELETE:
            if self.changes.has_key(dn):
                warning("%s had pending modifications" % dn)
            self.changes[dn] = [ Change(OP_DELETE, dn) ]
        elif op == OP_RENAME:
            if self.changes.has_key(dn):
                self.changes[dn].append( Change(OP_RENAME, dn, new, old) )
            else:
                self.changes[dn] = [ Change(OP_RENAME, dn, new, old) ]
        elif op == OP_CREATE:
            if self.changes.has_key(dn):
                warning("%s creation already pending" % dn)
                self.changes[dn].append( Change(OP_CREATE, dn, new) )
            else:
                self.changes[dn] = [ Change(OP_CREATE, dn, new) ]
        elif op == OP_MODIFY:
            if self.changes.has_key(dn):
                #warning("%s has uncommited changes" % dn)
                self.changes[dn].append( Change(OP_MODIFY, dn, new, old) )
            else:
                self.changes[dn] = [ Change(OP_MODIFY, dn, new, old) ]

    def cancel(self, dn, attribute = None):
        if self.changes.has_key(dn):
            del self.changes[dn]
        else:
            critical("%s not in change set" % dn)

    def __str__(self):
        result = '[ '
        for v in self.changes.itervalues():
            for _v in v:
                if _v.op == OP_MODIFY:
                    result += "(%s,'%s',%s, %s), " % (_v.op, _v.path, _v.old, _v.new)
                else:
                    result += "(%s,'%s','%s','%s'), " % (_v.op, _v.path, _v.old, _v.new)
        return result + ' ]'

    def __repr__(self):
        return self.__str__()
    
    def loadFromString(self, content):
        """Appends content to changeset."""
        for (op, path, new, old) in eval(content):
            self.add(path, op, new, old)

        
        
