import asyncio
import logging
import unittest
from asyncio import Queue
from types import CoroutineType

from ecmind_blue_client.pool import AsyncPoolClient
from ecmind_blue_client.rpc import Jobs
from tests._test_settings import ECM_SERVERS, ECM_USERNAME, ECM_PASSWORD

logging.basicConfig(level=logging.DEBUG)


class TestPoolAsync(unittest.IsolatedAsyncioTestCase):
    def setUp(self):
        self.client = AsyncPoolClient(servers=ECM_SERVERS, username=ECM_USERNAME, password=ECM_PASSWORD)

    def tearDown(self):
        del self.client

    async def test_simple_pool_call(self):

        result = await self.client.execute(Jobs.KRN_GETSERVERINFO, Flags=0, Info=6)
        self.assertEqual(result.get("Value", str), "oxtrodbc.dll")

    async def test_pooling(self):

        async def perform_task(client: AsyncPoolClient, errors: Queue):
            try:
                result = await client.execute(Jobs.KRN_GETSERVERINFO, Flags=0, Info=6)
                self.assertEqual(result.get("Value", str), "oxtrodbc.dll")
            except Exception as e:  # pylint: disable=broad-exception-caught
                await errors.put(e)

        # Define the number of threads to create.
        num_tasks = 20
        # Create an empty list to store thread objects.
        tasks: list[CoroutineType] = []

        # Create and start multiple threads.
        errors = Queue()

        await asyncio.gather(*(perform_task(self.client, errors) for _ in range(num_tasks)))

        # Assert that all threads have completed successfully (not alive).
        for t in tasks:
            self.assertFalse(t.cr_running)

        self.assertEqual(errors.qsize(), 0)


if __name__ == "__main__":
    unittest.main()
