import string,os
from MessageSource import Error,g_errorMessages
from Ft.Ods import LocalThreading

class FtodsBaseException(Exception):
    """Root of all Ftods Exceptions"""
    def __init__(self, errorCode,**args):
        self._msg = g_errorMessages[errorCode] % args
        self._errorCode = errorCode
        self._args = args
        Exception.__init__(self,self._msg)
        self.__dict__.update(args)

    def __str__(self):
        return self._msg

class FtodsSystemException(FtodsBaseException):
    """Root of all System exceptions (not user generated)"""
    pass

class FtodsUserException(FtodsBaseException):
    """Root of all user generated exceptions"""
    _members = {}
    name = 'Unknown Exception'
    def __init__(self,**args):
        baseArgs = []
        for name,default in self._members.items():
            self.__dict__[name] = args.get(name,default)
            baseArgs.append(self.__dict__[name])
        Exception.__init__(self,tuple(baseArgs))

    def __str__(self):
        msgs=["FtodsUserException: "]
        for m in self._members.keys():
            msgs.append(str(m)+' = '+str(self.__dict__[m]))
        return string.join(msgs,os.linesep+'\t')


#############################
#
# Exceptions defined in the book
#
#############################
class DatabaseClosed(FtodsSystemException):
    def __init__(self,dbName):
        FtodsSystemException.__init__(self,Error.DATABASE_CLOSED,dbName=dbName)

class TransactionInProgress(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.TRANSACTION_IN_PROGRESS,threadId=LocalThreading.GetThreadId())

class TransactionNotInProgress(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.TRANSACTION_NOT_IN_PROGRESS,threadId=LocalThreading.GetThreadId())

class IntegrityError(FtodsSystemException):
    def __init__(self, relName):
        FtodsSystemException.__init__(self,Error.INTEGRITY_ERROR,relationshipName=relName)

class LockNotGranted(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.LOCK_NOT_GRANTED)


class InvalidCollectionType(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.INVALID_COLLECTION_TYPE)

class ElementNotFound(FtodsSystemException):
    def __init__(self, element):
        FtodsSystemException.__init__(self,Error.ELEMENT_NOT_FOUND,element=element)

class NoMoreElements(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.NO_MORE_ELEMENTS)

class InvalidIndex(FtodsSystemException):
    def __init__(self,index):
        FtodsSystemException.__init__(self,Error.INVALID_INDEX,index=index)

class InvalidSize(FtodsSystemException):
    def __init__(self,size):
        FtodsSystemException.__init__(self,Error.INVALID_SIZE,size=size)


class DuplicateName(FtodsSystemException):
    def __init__(self,name):
        FtodsSystemException.__init__(self,Error.DUPLICATE_NAME,name=name)


class KeyNotFound(FtodsSystemException,KeyError):
    def __init__(self, key):
        FtodsSystemException.__init__(self,Error.KEY_NOT_FOUND,key=key)

class InvalidDate(FtodsSystemException):
    def __init__(self):
        FtodsSystemException.__init__(self,Error.INVALID_DATE)
    

class InvalidTimestamp(FtodsSystemException):
    def __init__(self,a_date, a_time):
        FtodsSystemException.__init__(self,Error.INVALID_TIME_STAMP,a_date = a_date,a_time = a_time)



class NameNotFound(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.NAME_NOT_FOUND,reason=reason)


class InvalidType(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.INVALID_TYPE,reason=reason)


class InvalidExpression(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.INVALID_EXPRESSION,reason=reason)


class CannotRemove(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.CANNOT_REMOVE,reason=reason)

class BadParameter(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.BAD_PARAMETER,reason=reason)


class BadRelationship(FtodsSystemException):
    def __init__(self,reason):
        FtodsSystemException.__init__(self,Error.BAD_RELATIONSHIP,reason=reason)



class DatabaseOpen(FtodsSystemException):
    def __init__(self,dbName):
        FtodsSystemException.__init__(self,Error.DATABASE_OPEN,dbName = dbName)
    
    
class DatabaseNotFound(FtodsSystemException):
    def __init__(self,dbName):
        FtodsSystemException.__init__(self,Error.DATABASE_NOT_FOUND,dbName = dbName)

    
class ObjectNameNotUnique(FtodsSystemException):
    def __init__(self,name):
        FtodsSystemException.__init__(self,Error.OBJECT_NAME_NOT_UNIQUE,name = name)

class ObjectNameNotFound(FtodsSystemException):
    def __init__(self,name):
        FtodsSystemException.__init__(self,Error.OBJECT_NAME_NOT_FOUND,name = name)




########################################
#
# 4ods specifiec exceptions
#
########################################
class FtodsObjectNotFound(FtodsSystemException):
    def __init__(self,oid,typ):
        from Ft.Ods import Constants
        FtodsSystemException.__init__(self,Error.OBJECT_NOT_FOUND,oid = oid, type = Constants.g_odmgTypeToString.get(typ,'Unknown Type %s' % typ))

class FtodsUnsupportedError(FtodsSystemException):
    def __init__(self,feature):
        FtodsSystemException.__init__(self,Error.UNSUPPORTED_ERROR,feature = feature)

class FtodsUnknownError(FtodsSystemException):
    def __init__(self,msg):
        FtodsSystemException.__init__(self,Error.UNKNOWN_ERROR,msg = msg)

class FtodsInvalidConnectionString(FtodsSystemException):
    def __init__(self,connectString,reason):
        FtodsSystemException.__init__(self,Error.INVALID_CONNECTION_STRING,connectString = connectString, reason = reason)

class FtodsInvalidPythonClass(FtodsSystemException):
    def __init__(self,classId):
        FtodsSystemException.__init__(self,Error.INVALID_PYTHON_CLASS,classId = classId)

class FtodsGenerationError(FtodsSystemException):
    def __init__(self,msg):
        FtodsSystemException.__init__(self,Error.GENERATION_ERROR,msg=msg)

class FtodsPostProcessorError(FtodsSystemException):
    def __init__(self,msg):
        FtodsSystemException.__init__(self,Error.POST_PROCESSOR_ERROR,msg=msg)

class FtodsInterfaceCreationError(FtodsSystemException):
    def __init__(self,name):
        FtodsSystemException.__init__(self,Error.INTERFACE_CREATION_ERROR,name=name)


########################################
#
# 4ods specifiec exceptions for user operations
#
########################################
class FtodsOperationNotImplemented(FtodsSystemException):
    def __init__(self,name):
        FtodsSystemException.__init__(self,Error.OPERATION_NOT_IMPLEMENTED,name=name)
    
class FtodsOperationBadParam(FtodsSystemException):
    def __init__(self,name,type,value):
        FtodsSystemException.__init__(self,Error.OPERATION_BAD_PARAM,name=name,value=str(value),type=type)


class FtodsOperationBadDefinition(FtodsSystemException):
    def __init__(self,repoId,tb):
        FtodsSystemException.__init__(self,Error.OPERATION_BAD_DEFINITION,repoId=repoId,tb=tb)
