import functools


def decorated_job(decorate_out=None, decorate_err=None, decorate_log=None):
    """Setup stdout/stderr/log decoration for the given coroutine.

    This is the same as wrapping the entire coroutine in:

        with ctx.decoration(...):
            ...

    Use as a decorator:

        @decorated_job()
        async def my_job(ctx):
            logger.info('hello')
            await asyncio.sleep(1)
            logger.info(world')

        @decorated_job(decorate_out='DECORATED: ')
        async def my_other_job(ctx):
            with ctx.stdout as f:
                print('hello', file=f)
                await asyncio.sleep(1)
                print(again', file=f)

    See Context.decoration() for more details
    """

    def wrap(coro):
        @functools.wraps(coro)
        async def wrapped_coro(ctx):
            with ctx.decoration(
                decorate_out=decorate_out,
                decorate_err=decorate_err,
                decorate_log=decorate_log,
            ):
                return await coro(ctx)

        return wrapped_coro

    return wrap