#!/usr/bin/env python

import json
from functools import wraps
from decorator import decorator
from dm.common.exceptions.dmException import DmException
from dm.common.utility.loggingManager import LoggingManager

class DmApi(object):
    """ Base dm api class. """
    def __init__(self, username = None, password = None):
        self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)

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

    @classmethod
    def toDmObjectList(cls, dictList, dmObjectClass):
        dmObjectList = []
        for dict in dictList:
            dmObjectList.append(dmObjectClass(dict))
        return dmObjectList 

    # Exception decorator for all api calls
    @classmethod
    def execute(cls, func):
        def decorate(*args, **kwargs):
            try:
                response = func(*args, **kwargs)
                return response
            except DmException, ex:
                raise
            except Exception, ex:
                cls.getLogger().exception('%s' % ex)
                raise DmException(exception=ex)
        return decorate

    # Exception decorator for api calls
    # Use two decorators for the sake of documentation
    @classmethod
    def execute2(cls, *dargs, **dkwargs):
        def internalCall(func):
            @wraps(func)
            def wrappedCall(func, *args, **kwargs):
                try:
                    response = func(*args, **kwargs)
                    return response
                except DmException, ex:
                    raise
                except Exception, ex:
                    cls.getLogger().exception('%s' % ex)
                    raise DmException(exception=ex)
            return decorator(wrappedCall, func)
        if len(dargs) == 1 and callable(dargs[0]):
            return internalCall(dargs[0])
        else:
            return internalCall