import logging
import threading
import unittest
from queue import Queue

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


class TestPoolSync(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.client = SyncPoolClient(servers=ECM_SERVERS, username=ECM_USERNAME, password=ECM_PASSWORD)

    @classmethod
    def tearDownClass(cls):
        del cls.client

    def test_simple_pool_call(self):

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

    def test_pooling(self):

        def perform_task(client: SyncPoolClient, errors: Queue):
            try:
                logging.info("In Use %d", client.connections_in_use)
                result = 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
                print(e)
                errors.put(e)

        # Define the number of threads to create.
        num_threads = 20
        # Create an empty list to store thread objects.
        threads: list[threading.Thread] = []

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

        for _ in range(num_threads):
            t = threading.Thread(target=perform_task, args=[self.client, errors])
            threads.append(t)
            t.start()

        for t in threads:
            t.join()

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

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


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