from unittest import TestCase

from edpdependencyinjection import DependencyLoader

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


class TestDiMessageMessageProcessorBuilder(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 = DiMessageMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={0x01: SimpleProcessor}
        )
        processor = builder.build_message_processor(0x01)
        self.assertIsNotNone(processor)
        self.assertIsInstance(processor, SimpleProcessor)

    def test_build_message_processor_with_instance(self):
        instance = SimpleProcessor()
        builder = DiMessageMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={0x01: instance}
        )
        processor = builder.build_message_processor(0x01)
        self.assertIs(processor, instance)

    def test_build_message_processor_multiple_tokens(self):
        builder = DiMessageMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={
                0x01: SimpleProcessor,
                0x02: AnotherProcessor,
            }
        )
        processor_a = builder.build_message_processor(0x01)
        processor_b = builder.build_message_processor(0x02)
        self.assertIsInstance(processor_a, SimpleProcessor)
        self.assertIsInstance(processor_b, AnotherProcessor)

    def test_build_message_processor_dict(self):
        builder = DiMessageMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={
                0x01: SimpleProcessor,
                0x02: AnotherProcessor,
            }
        )
        result = builder.build_message_processor_dict()
        self.assertIn(0x01, result)
        self.assertIn(0x02, result)
        self.assertIs(result[0x01], builder)
        self.assertIs(result[0x02], builder)

    def test_build_message_processor_token_not_found(self):
        builder = DiMessageMessageProcessorBuilder(
            dependency_context=self.dependency_context,
            processor_definitions={0x01: SimpleProcessor}
        )
        with self.assertRaises(KeyError):
            builder.build_message_processor(0xFF)
