# -*- coding: utf-8 -*-
"""
    tornadio2.tests.gen
    ~~~~~~~~~~~~~~~~~~~

    :copyright: (c) 2011 by the Serge S. Koval, see AUTHORS for more details.
    :license: Apache, see LICENSE for more details.
"""

from collections import deque

from nose.tools import eq_

from tornadio2 import gen

_queue = None


def init_environment():
    global _queue
    _queue = deque()


def run_sync(test, callback):
    callback(test)


def queue_async(test, callback):
    global _queue
    _queue.append((callback, test))


def step_async():
    callback = _queue.popleft()
    callback[0](callback[1])


def run_async():
    global _queue

    while True:
        try:
            step_async()
        except IndexError:
            break


def run_async_oor():
    global _queue

    while True:
        try:
            callback = _queue.pop()
            callback[0](callback[1])
        except IndexError:
            break


class Dummy():
    def __init__(self, queue_type):
        self.v = None
        self.queue_type = queue_type

    @gen.sync_engine
    def test(self, value):
        self.v = yield gen.Task(self.queue_type, value)


class DummyList():
    def __init__(self, queue_type):
        self.v = []
        self.queue_type = queue_type

    @gen.sync_engine
    def test(self, value):
        self.v.append((yield gen.Task(self.queue_type, value)))


class DummyListOutOfOrder():
    def __init__(self, queue_type):
        self.v = []
        self.queue_type = queue_type

    @gen.engine
    def test(self, value):
        self.v.append((yield gen.Task(self.queue_type, value)))


class DummyLoop():
    def __init__(self, queue_type):
        self.v = 0
        self.queue_type = queue_type

    @gen.sync_engine
    def test(self, value):
        for n in range(2):
            self.v += (yield gen.Task(self.queue_type, value))

def test():
    init_environment()

    dummy = Dummy(run_sync)
    dummy.test('test')

    eq_(dummy.v, 'test')


def test_async():
    init_environment()

    dummy = Dummy(queue_async)
    dummy.test('test')
    run_async()

    # Verify value
    eq_(dummy.v, 'test')


def test_sync_queue():
    init_environment()

    dummy = DummyList(queue_async)
    dummy.test('1')
    dummy.test('2')
    dummy.test('3')
    run_async()

    # Verify value
    eq_(dummy.v, ['1', '2', '3'])


def test_sync_queue_oor():
    init_environment()

    dummy = DummyList(queue_async)
    dummy.test('1')
    dummy.test('2')
    dummy.test('3')
    run_async_oor()

    # Verify value
    eq_(dummy.v, ['1', '2', '3'])


def test_async_queue_oor():
    init_environment()

    dummy = DummyListOutOfOrder(queue_async)
    dummy.test('1')
    dummy.test('2')
    dummy.test('3')
    run_async_oor()

    # Verify value
    eq_(dummy.v, ['3', '2', '1'])

[((21, 13, 21, 20), 'collections.deque', 'deque', ({}, {}), '()', False, 'from collections import deque\n'), ((105, 4, 105, 24), 'nose.tools.eq_', 'eq_', ({(105, 8, 105, 15): 'dummy.v', (105, 17, 105, 23): '"""test"""'}, {}), "(dummy.v, 'test')", False, 'from nose.tools import eq_\n'), ((116, 4, 116, 24), 'nose.tools.eq_', 'eq_', ({(116, 8, 116, 15): 'dummy.v', (116, 17, 116, 23): '"""test"""'}, {}), "(dummy.v, 'test')", False, 'from nose.tools import eq_\n'), ((129, 4, 129, 33), 'nose.tools.eq_', 'eq_', ({(129, 8, 129, 15): 'dummy.v', (129, 17, 129, 32): "['1', '2', '3']"}, {}), "(dummy.v, ['1', '2', '3'])", False, 'from nose.tools import eq_\n'), ((142, 4, 142, 33), 'nose.tools.eq_', 'eq_', ({(142, 8, 142, 15): 'dummy.v', (142, 17, 142, 32): "['1', '2', '3']"}, {}), "(dummy.v, ['1', '2', '3'])", False, 'from nose.tools import eq_\n'), ((155, 4, 155, 33), 'nose.tools.eq_', 'eq_', ({(155, 8, 155, 15): 'dummy.v', (155, 17, 155, 32): "['3', '2', '1']"}, {}), "(dummy.v, ['3', '2', '1'])", False, 'from nose.tools import eq_\n'), ((66, 23, 66, 55), 'tornadio2.gen.Task', 'gen.Task', ({(66, 32, 66, 47): 'self.queue_type', (66, 49, 66, 54): 'value'}, {}), '(self.queue_type, value)', False, 'from tornadio2 import gen\n'), ((76, 29, 76, 61), 'tornadio2.gen.Task', 'gen.Task', ({(76, 38, 76, 53): 'self.queue_type', (76, 55, 76, 60): 'value'}, {}), '(self.queue_type, value)', False, 'from tornadio2 import gen\n'), ((86, 29, 86, 61), 'tornadio2.gen.Task', 'gen.Task', ({(86, 38, 86, 53): 'self.queue_type', (86, 55, 86, 60): 'value'}, {}), '(self.queue_type, value)', False, 'from tornadio2 import gen\n'), ((97, 29, 97, 61), 'tornadio2.gen.Task', 'gen.Task', ({(97, 38, 97, 53): 'self.queue_type', (97, 55, 97, 60): 'value'}, {}), '(self.queue_type, value)', False, 'from tornadio2 import gen\n')]