from unittest import TestCase

from edpdependencyinjection import DependencyLoader
from messageprocessor import DefaultMessageProcessorExecutor

import testmodule
from dimessageprocessor import DiMessageProcessorExecutorFactory
from testmodule.processor import SimpleProcessor
from testmodule.callback import TestCallback


class TestDiMessageProcessorExecutorFactory(TestCase):

    def setUp(self):
        self.dependency_loader = DependencyLoader()
        self.dependency_loader.load_modules(modules=[testmodule])
        self.dependency_context = self.dependency_loader.build_context()

    def test_build_executor_with_callbacks(self):
        factory = DiMessageProcessorExecutorFactory(
            dependency_context=self.dependency_context,
            callback_definitions=[TestCallback]
        )
        processor = SimpleProcessor()
        executor = factory.build_executor(processor)
        self.assertIsNotNone(executor)
        self.assertIsInstance(executor, DefaultMessageProcessorExecutor)

    def test_build_executor_with_empty_callbacks(self):
        factory = DiMessageProcessorExecutorFactory(
            dependency_context=self.dependency_context,
            callback_definitions=[]
        )
        processor = SimpleProcessor()
        executor = factory.build_executor(processor)
        self.assertIsNotNone(executor)
        self.assertIsInstance(executor, DefaultMessageProcessorExecutor)

    def test_build_executor_resolves_callback_instances(self):
        factory = DiMessageProcessorExecutorFactory(
            dependency_context=self.dependency_context,
            callback_definitions=[TestCallback]
        )
        processor = SimpleProcessor()
        executor = factory.build_executor(processor)
        self.assertEqual(len(executor.callbacks), 1)
        self.assertIsInstance(executor.callbacks[0], TestCallback)

    def test_build_executor_multiple_callbacks(self):
        factory = DiMessageProcessorExecutorFactory(
            dependency_context=self.dependency_context,
            callback_definitions=[TestCallback, TestCallback]
        )
        processor = SimpleProcessor()
        executor = factory.build_executor(processor)
        self.assertEqual(len(executor.callbacks), 2)
