from unittest.mock import patch, MagicMock
from celery_test_utils import BaseTest 

import celery
import celery_exporter.monitor
from celery_exporter.core import CeleryExporter

prom_http_server_mock = MagicMock(return_value=None)
setup_metrics_mock = MagicMock(return_value=None)
task_thread_mock = MagicMock(spec=celery_exporter.monitor.TaskThread)
worker_thread_mock = MagicMock(spec=celery_exporter.monitor.WorkerMonitoringThread)
event_thread_mock = MagicMock(spec=celery_exporter.monitor.EnableEventsThread)


@patch('celery.task.control.inspect.registered_tasks', {'worker1': [BaseTest.task]})
@patch('celery_exporter.core.prometheus_client.start_http_server', prom_http_server_mock)
@patch('celery_exporter.core.setup_metrics', setup_metrics_mock)
@patch('celery_exporter.core.TaskThread', task_thread_mock)
@patch('celery_exporter.core.WorkerMonitoringThread', worker_thread_mock)
@patch('celery_exporter.core.EnableEventsThread', event_thread_mock)
class TestCeleryExporter(BaseTest):
    
    def setUp(self):
        self.cel_exp = CeleryExporter(broker_url='memory://', listen_address='127.0.0.1:9090', max_tasks=TestCeleryExporter.max_tasks, namespace=TestCeleryExporter.namespace, enable_events=True)
   
    def test_setup_metrics(self):
        self.cel_exp.start()
        setup_metrics_mock.assert_called_with(self.cel_exp._app, TestCeleryExporter.namespace)
    
    def test_http_server(self):
        self.cel_exp.start()
        prom_http_server_mock.assert_called_with(9090, '127.0.0.1')

    def test_task_thread(self):
        self.cel_exp.start()
        task_thread_mock.assert_called_with(self.cel_exp._app, TestCeleryExporter.namespace, TestCeleryExporter.max_tasks)
    
    def test_worker_thread(self):
        self.cel_exp.start()
        worker_thread_mock.assert_called_with(self.cel_exp._app, TestCeleryExporter.namespace)
    
    def test_event_thread(self):
        self.cel_exp.start()
        event_thread_mock.assert_called_with(self.cel_exp._app)

