from unittest import TestCase

from edpdependencyinjection import DependencyLoader

import testmodule
from dimessageprocessor import DiEventMessageProcessorBuilder
from testmodule.processor import SimpleProcessor, AnotherProcessor


class TestDiEventMessageProcessorBuilder(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_message_processor_with_type(self):
        builder = DiEventMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={"order_created": SimpleProcessor}
        )
        processor = builder.build_message_processor("order_created")
        self.assertIsNotNone(processor)
        self.assertIsInstance(processor, SimpleProcessor)

    def test_build_message_processor_with_instance(self):
        instance = SimpleProcessor()
        builder = DiEventMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={"order_created": instance}
        )
        processor = builder.build_message_processor("order_created")
        self.assertIs(processor, instance)

    def test_build_message_processor_multiple_keys(self):
        builder = DiEventMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={
                "order_created": SimpleProcessor,
                "order_cancelled": AnotherProcessor,
            }
        )
        processor_a = builder.build_message_processor("order_created")
        processor_b = builder.build_message_processor("order_cancelled")
        self.assertIsInstance(processor_a, SimpleProcessor)
        self.assertIsInstance(processor_b, AnotherProcessor)

    def test_build_message_processor_dict(self):
        builder = DiEventMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={
                "order_created": SimpleProcessor,
                "order_cancelled": AnotherProcessor,
            }
        )
        result = builder.build_message_processor_dict()
        self.assertIn("order_created", result)
        self.assertIn("order_cancelled", result)
        self.assertIs(result["order_created"], builder)
        self.assertIs(result["order_cancelled"], builder)

    def test_build_message_processor_key_not_found(self):
        builder = DiEventMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={"order_created": SimpleProcessor}
        )
        with self.assertRaises(KeyError):
            builder.build_message_processor("unknown_event")
