from com.orangescape.entity import DbData
from orangescape.model.server.SystemInterface import Dynamic,Static,Data
import logging

class AbstractData(Data):

    def __init__(self, SheetId, data = None):
        if data is None:
            self._dynamic_properties = dict()
            self.SheetId = SheetId
        else:
            self._dynamic_properties = data

    def setSheetId(self, SheetId):
        raise NotImplementedError

    def getSheetId(self):
        raise NotImplementedError

    def setMetadataId(self, metadataId):
        raise NotImplementedError

    def getMetadataId(self):
        raise NotImplementedError

    def setModifiedAt(self, modifiedAt):
        raise NotImplementedError

    def getModifiedAt(self):
        raise NotImplementedError

    def setApplicationId(self, applicationId):
        raise NotImplementedError

    def getApplicationId(self):
        raise NotImplementedError

    def get(self,cellMetadata):
        raise NotImplementedError

    def set(self,cellMetadata,value):
        raise NotImplementedError

    def getCopy(self):
        raise NotImplementedError

class PrimaryData(AbstractData,DbData):

    __logger = logging.getLogger()

    def __init__(self,session,sessionData=None):
        if sessionData is None:
            DbData.__init__(self)
            self.setSession(session)
            DbData.set(self, 'Version', 0)
        else:
            DbData.__init__(self,sessionData)
            self.setSession(session)

    def get(self,cellMetadata):
        if cellMetadata.isReferenceCell():
            sessiondata = DbData.get(self,cellMetadata.getSheetId())
            if sessiondata is not None:
                return self.getSession().getHibernateSession().getIdentifier(sessiondata)
            else:
                return None
        else:
            return DbData.get(self,cellMetadata.getSheetId())

    def set(self,cellMetadata,value):
        if not cellMetadata.isReferenceCell():
            if cellMetadata.isStr():
                if value is not None:
                    value=str(value)
                DbData.set(self,cellMetadata.getSheetId(), value)
            else:
                try:
                    value = float(value or 0.0) or None
                except ValueError,ve:
                    logging.warn('got an unparsable string value \''+value+'\'for number type \''+cellMetadata.getSheetId()+'\'')
                    value = None;
                DbData.set(self,cellMetadata.getSheetId(),value)
        else:
            ref_name = cellMetadata.getCellName()+'_'+cellMetadata.getSheetId()
            # Removing the old_cache_key from the cache
            if self.get(cellMetadata) is not None:
                old_cache_key=self.get(cellMetadata)+'.'+cellMetadata.getCellName()+'.'+cellMetadata.getSheetMetadata().getSheetName()
                self.getSession().removeFromCache(old_cache_key)
            if value is not None:
                if value.__class__.__name__=='HashMap':
                    value=value.get('SheetId')
                # Removing the new_cache_key from the cache since it will be also invalidated
                new_cache_key = value+'.'+cellMetadata.getCellName()+'.'+cellMetadata.getSheetMetadata().getSheetName()
                self.getSession().removeFromCache(new_cache_key)
                self.setReference(cellMetadata.getSheetId(),cellMetadata.getReferredSheetMetadata().getSheetName(),value,ref_name)
            else:
                self.setReference(cellMetadata.getSheetId(),cellMetadata.getReferredSheetMetadata().getSheetName(),value,ref_name)

    def setSheetId(self, value):
        DbData.setSheetId(self,value)

    def getSheetId(self):
        return DbData.getSheetId(self)

    def setModifiedAt(self, value):
        DbData.setModifiedAt(self,value)

    def getModifiedAt(self):
        return DbData.getModifiedAt(self)

    def setApplicationId(self, value):
        self.appId=value

    def getApplicationId(self):
        return self.appId

    def getSheetMetadataId(self):
        return self.metadataId

    def setSheetMetadataId(self, value):
        self.metadataId=value

    def getCopy(self):
        return self

    def getClass(self):
        return PrimaryData

    appId=None
    metadataId=None
    SheetMetadataId = property(getSheetMetadataId, setSheetMetadataId)
    SheetId = property(getSheetId, setSheetId)
    ApplicationId = property(getApplicationId, setApplicationId)
    ModifiedAt = property(getModifiedAt, setModifiedAt)

class SecondaryData(AbstractData):

     def get(self,cellMetadata):
        return DbData.get(self,cellMetadata.getCellName())

class OriginalData(AbstractData):
    SheetMetadataId = str()
    SheetId = str()
    ApplicationId = str()
    _dynamic_properties = dict()
    def __init__(self, SheetMetadataId, SheetId, ApplicationId, _dynamic_properties):
        self.SheetMetadataId = SheetMetadataId
        self.SheetId = SheetId
        self.ApplicationId = ApplicationId
        self._dynamic_properties = _dynamic_properties

