import queue
from threading import Thread

from src.primes import PrimesInMem, PrimesToQueue, PrimesOnDisk


def test_primesinmem():
    expected_values = [exp for exp in range(0, 10_000)]
    actual = PrimesInMem()
    for i, exp_val in enumerate(expected_values):
        actual.append(exp_val)

        assert (len(actual) == i + 1)

        for j, p in enumerate(actual):
            assert p == expected_values[j]
    assert list(actual) == expected_values


def test_primesinqueue():
    def _dummy_consumer_primesinqueue(in_queue: queue.Queue) -> None:
        while True:
            prime = in_queue.get()
            in_queue.task_done()
            if prime is None:
                break

    expected_values = [exp for exp in range(0, 10_000)]
    primes_queue = queue.Queue(maxsize=0)
    actual = PrimesToQueue(primes_queue)
    consumer_thread = Thread(target=_dummy_consumer_primesinqueue, args=(primes_queue,))
    consumer_thread.start()
    for i, exp_val in enumerate(expected_values):
        actual.append(exp_val)

        assert (len(actual) == i + 1)
    list(actual)
    consumer_thread.join()


def test_primesondisk():
    expected_values = [exp for exp in range(0, 10_000)]
    actual = PrimesOnDisk(max_mem_buffer=750)
    for i, exp_val in enumerate(expected_values):
        actual.append(exp_val)

        assert (len(actual) == i + 1)

        for j, p in enumerate(actual):
            assert p == expected_values[j]
    assert [a for a in actual] == expected_values
    assert len(actual) == len(expected_values)
