#!/usr/bin/env python

import copy
import types
import re

from dm.common.exceptions.dmException import DmException
from dm.common.utility.loggingManager import LoggingManager
from dm.common.mongodb.impl.mongoDbManager import MongoDbManager

class DmMongoDbApi:
    """ Base Mongo DB API class. """

    SYSTEM_KEY_LIST = ['_id']
    REGEX_IGNORE_KEY_LIST = ['_id']
    REGEX_IGNORE_CASE_KEY = '_ignoreCase'

    def __init__(self):
        self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
        self.dbClient = MongoDbManager.getInstance().getDbClient()

    # Decorator for all DB methods
    @classmethod
    def executeDbCall(cls, func):
        def dbCall(*args, **kwargs):
            try:
                try:
                    return func(*args, **kwargs)
                except DmException, ex:
                    raise
                except Exception, ex:
                    cls.getLogger().exception('%s' % ex)
                    raise DmException(exception=ex)
            finally:
                # For now, do nothing
                pass
        return dbCall

    @classmethod
    def getLogger(cls):
        logger = LoggingManager.getInstance().getLogger(cls.__name__)
        return logger

    @classmethod
    def listToDmObjects(cls, mongoDbObjectList, dmObjectClass):
        dmObjectList = []
        for o in mongoDbObjectList:
            dmObjectList.append(cls.toDmObject(o, dmObjectClass))
        return dmObjectList

    @classmethod
    def toDmObject(cls, mongoDbObject, dmObjectClass):
        cls.scrubMongoDbObject(mongoDbObject)
        return dmObjectClass(mongoDbObject)

    @classmethod
    def scrubMongoDbObject(cls, mongoDbObject):
        for key in cls.SYSTEM_KEY_LIST:
            if mongoDbObject.has_key(key):
                # Remove leading underscore
                newKey = key[1:]
                mongoDbObject[newKey] = str(mongoDbObject[key])
                del mongoDbObject[key]

    @classmethod
    def getMongoDict(cls, dict):
        mongoDict = copy.copy(dict)
        for key in cls.SYSTEM_KEY_LIST:
            # if dictionary has system key, do not modify it
            if mongoDict.has_key(key):
                continue
            # If provided dict has system key without leading underscore
            # modify it
            key2 = key[1:]
            if mongoDict.has_key(key2):
                mongoDict[key] = mongoDict[key2]
                del mongoDict[key2]
        return mongoDict

    @classmethod
    def convertStringsToRegex(cls, dict, ignoreCase=True):
        dict2 = copy.copy(dict)
        for (key,value) in dict2.items():
            if key in cls.REGEX_IGNORE_KEY_LIST:
                continue
            elif type(value) == types.StringType or type(value) == types.UnicodeType:
                cls.getLogger().debug('Converting to regex: %s for key %s' % (value,key))
                if ignoreCase:
                    regex = re.compile(value, re.IGNORECASE)
                else:
                    regex = re.compile(value)
                dict2[key] = regex
        return dict2

#######################################################################
# Testing.
if __name__ == '__main__':
    api = DmMongoDbApi()