import logging

"""
logLevel
logging.CRITICAL
logging.ERROR
logging.WARNING
logging.INFO
logging.DEBUG
logging.NOTSET
"""


def buildConsoleHandler(logLevel):
  consoleHandler = logging.StreamHandler();
  consoleHandler.setLevel(logLevel);
  consoleHandler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'));
  return consoleHandler;

def buildFileHandler(logLevel,filename):
  fileHandler = logging.FileHandler(filename);
  fileHandler.setLevel(logLevel);
  fileHandler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'));
  return fileHandler;

def info(func):
  logger = logging.getLogger(__name__)
  def log(*args, **kwargs):
    logger.info(func.__name__);
    return func(*args, **kwargs);
  log.__name__ = func.__name__;
  return log;

def debug(func):
  logger = logging.getLogger(__name__)
  def log(*args, **kwargs):
    ret = func(*args, **kwargs);
    logger.debug(func.__name__+" param "+str(args)+str(kwargs)+" Return "+str(ret));
    return ret;
  log.__name__ = func.__name__;
  return log;

def error(exception):
  logger = logging.getLogger(__name__)
  def decorate(func):
    def log(*args, **kwargs):
      try:
        ret = func(*args, **kwargs);
      except exception as e:
        logger.error(func.__name__+" param "+str(args)+str(kwargs)+" Raise "+exception.__name__+e.__doc__+"("+e.message+")");
        #raise e;
      return ret;
    log.__name__ = func.__name__;
    return log;
  return decorate;

def null(default):
  def decorate(func):
    def decorator(*args, **kwargs):
      ret = func(*args, **kwargs);
      if ret == None:
        ret = default;
      return ret;
    return decorator;
  return decorate;

if __name__ == "__main__":
  logger = logging.getLogger(__name__)
  logger.setLevel(logging.DEBUG)

  logger.addHandler(buildConsoleHandler(logging.DEBUG))
  logger.addHandler(buildFileHandler(logging.WARNING,"warning.log"))

  @debug
  def test2(a):
    return a;

  @debug
  @info
  def test(a):
    return test2(a);

  @error(KeyboardInterrupt)
  def test3():
    raise KeyboardInterrupt

  # 'application' code
  logger.debug('debug message')
  logger.info('info message')
  logger.warn('warn message')
  logger.error('error message')
  logger.critical('critical message')
  test(2);
  try:
    test3();
  except:
    pass;

  @null("B==D")
  def pop(a):
    return None;

  print pop(None);

