import univention.debug as ud
import time
from functools import wraps
import inspect

def Function(func=None, with_args=True, with_return=False):

	def _decorator(func):
		func_name = func.__name__
		is_method = inspect.getargspec(func).args[:1] == ['self']
		func_name = '%s.%s' % (func.__module__, func_name)

		@wraps(func)
		def _decorated(*args, **kwargs):
			class_name = '.%s' % type(args[0]).__name__ if is_method else ''
			text = '%s%s.%s(%s)' % (func.__module__, class_name, func.__name__, ('%r, %r' % (args, kwargs)) if with_args else '')
			_d = ud.function(text)
			result = func(*args, **kwargs)
			if with_return:
				_d.text = '%s -> %r' % (_d.text, result)
			return result
		return _decorated
	if func is None:
		return _decorator
	return _decorator(func)


ud.Function = Function


if __name__ == '__main__':
	ud.init('stdout', ud.NO_FLUSH, ud.FUNCTION)

	def foo():
		_d = ud.function('foo')
		time.sleep(0.5)

	@ud.Function
	def bar(*args, **kwargs):
		time.sleep(1)

	class Baz(object):

		@ud.Function(with_args=False, with_return=True)
		def baz(self, x):
			time.sleep(x)
			return x ** x

	foo()
	bar('x', 'y', 'z', blub=1)
	Baz().baz(1)
