import os
import unittest
from src.services.tracker.rabbitmq_client import RabbitMQClient
from unittest.mock import patch


class ResourcesMonitorTest(unittest.TestCase):

    class MockChannel:
        def __init__(self):
            pass

        def exchange_declare(self, exchange, exchange_type):
            pass

        def basic_publish(self, exchange, routing_key, body):
            pass

    class MockConnection:
        def channel(self):
            return ResourcesMonitorTest.MockChannel()

        def close(self):
            pass

    @patch("pika.BlockingConnection", return_value=None)
    @patch("pika.BlockingConnection.channel", return_value=None)
    def test_one_ok(self, connection, channel):
        with self.assertRaises(Exception):
            self.rmq = RabbitMQClient()

    @patch("pika.BlockingConnection", return_value=None)
    @patch("pika.BlockingConnection.channel", return_value=None)
    def test_one_ok_with_config_path(self, connection, channel):
        os.environ["CFG_PATH"] = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                              "../../../src/services/tracker/config.cfg")
        with self.assertRaises(Exception):
            self.rmq = RabbitMQClient()

    @patch("pika.BlockingConnection", return_value=MockConnection())
    @patch("pika.BlockingConnection.channel", return_value=None)
    def test_send_message_failure(self, connection, channel):
        self.rmq = RabbitMQClient()
        self.rmq.channel = None
        with self.assertRaises(Exception):
            self.rmq.send_message("asda", "as")

    @patch("pika.BlockingConnection", return_value=MockConnection())
    def test_send_message_ok(self, connection):
        self.rmq = RabbitMQClient()
        self.rmq.send_message("asda", "as")

    @patch("pika.BlockingConnection", return_value=MockConnection())
    @patch("pika.BlockingConnection.channel", return_value=None)
    def test_close_connection_failure(self, connection, channel):
        self.rmq = RabbitMQClient()
        self.rmq.connection = None
        with self.assertRaises(Exception):
            self.rmq.close_connection()

    @patch("pika.BlockingConnection", return_value=MockConnection())
    def test_close_connection_ok(self, connection):
        self.rmq = RabbitMQClient()
        self.rmq.close_connection()

    def test_get_exchange_params_sat_id_ok(self):
        os.environ["SATELLITE_ID"] = "test"
        _, routing_key = RabbitMQClient.get_exchange_params("test")
        self.assertEqual(routing_key, "test")
        os.environ.pop('SATELLITE_ID', None)

    def test_get_exchange_params_sat_group_ok(self):
        os.environ["SATELLITE_GROUP"] = "test"
        exchange_name, _ = RabbitMQClient.get_exchange_params("tracker")
        self.assertEqual(exchange_name, "test")
        os.environ.pop('SATELLITE_GROUP', None)

    def test_get_exchange_params_resources_exchange(self):
        os.environ["RESOURCES_EXCHANGE"] = "test"
        exchange_name, _ = RabbitMQClient.get_exchange_params("resources")
        self.assertEqual(exchange_name, "test")
        os.environ.pop('RESOURCES_EXCHANGE', None)

    def test_get_exchange_params_empty_exchange_name(self):
        os.environ[""] = "test"
        exchange_name, _ = RabbitMQClient.get_exchange_params("")
        self.assertIsNone(exchange_name)
        os.environ.pop('RESOURCES_EXCHANGE', None)


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