import logging
logger = logging.getLogger('django')

import functools
from tornado.ioloop import IOLoop


class ttask(object):

    """Run a task as a tornado callback. Greate for async background code.
    If tornado is not running, then things are run synchronously."""
    __name__ = "ttask"

    def __init__(self, *args, **kwargs):
        """When this gets more advance we can use this to setup
        more complicated features such as distributting to a true
        task service.

        :param *args: arg description
        :type *args: type description
        :param **kwargs: arg description
        :type **kwargs: type description
        """
        self._args = args
        self._kwargs = kwargs
    #__init__()

    def __call__(self, func):
        """todo: Docstring for __call__

        :param *args: arg description
        :type *args: type description
        :param **kwargs: arg description
        :type **kwargs: type description
        :return:
        :rtype:
        """

        logger.debug(
            "ttask decorate, IOLoop is running? %s", IOLoop.current()._running)

        @functools.wraps(func)
        def decorated(self, *args, **kwargs):
            """todo: Docstring for decorated

            :param *args: arg description
            :type *args: type description
            :param **kwargs: arg description
            :type **kwargs: type description
            :return:
            :rtype:
            """
            return IOLoop.current().add_callback(func, args, kwargs)
        # decorated()

        @functools.wraps(func)
        def sync_decorated(self, *args, **kwargs):
            """Run the function synchronously
            """
            return IOLoop.current().run_sync(
                functools.partial(func, *args, **kwargs))
        # decorated()

        if not IOLoop.current()._running:
            logger.debug("ttask running %s sync", func)
            return sync_decorated

        logger.debug("ttask running %s async", func)
        return decorated
    #__call__()
# ttask
