import logging
from datetime import datetime


def TimedCommand(functor, *args, **kwargs):
  """Wrapper for simple log timing of other python functions.

  If you want to log info about how long it took to run an arbitrary command,
  you would do something like:
    TimedCommand(RunCommand, ['wget', 'http://foo'])

  Args:
    functor: The function to run.
    args: The args to pass to the function.
    kwargs: Optional args to pass to the function.
    timed_log_level: The log level to use (defaults to logging.INFO).
    timed_log_msg: The message to log after the command completes.  It may have
      keywords: "name" (the function name), "args" (the args passed to the
      func), "kwargs" (the kwargs passed to the func), "ret" (the return value
      from the func), and "delta" (the timing delta).
    timed_log_callback: Function to call upon completion (instead of logging).
      Will be passed (log_level, log_msg, result, datetime.timedelta).
  """
  log_msg = kwargs.pop(
      'timed_log_msg',
      '%(name)s(*%(args)r, **%(kwargs)r)=%(ret)s took: %(delta)s')
  log_level = kwargs.pop('timed_log_level', logging.INFO)
  log_callback = kwargs.pop('timed_log_callback', None)
  start = datetime.now()
  ret = functor(*args, **kwargs)
  delta = datetime.now() - start
  log_msg %= {
      'name': getattr(functor, '__name__', repr(functor)),
      'args': args,
      'kwargs': kwargs,
      'ret': ret,
      'delta': delta,
  }
  if log_callback is None:
    logging.log(log_level, log_msg)
  else:
    log_callback(log_level, log_msg, ret, delta)
  return ret