import unittest
from typing import Dict

from src.vaitty_eventbus import EventHandlerFactory, EventChannel, Event, ConsoleEventChannel, FileEventChannel, \
    HttpEventChannel


class TestFactory(unittest.TestCase):
    def test_factory_from_config_console(self):
        handler = EventHandlerFactory.from_config()
        self.assertIsInstance(handler.channel, ConsoleEventChannel)

    def test_factory_from_config_file(self):
        config = {"EVENTBUS_CHANNEL": "file", "EVENTBUS_FILE": "test.log"}
        handler = EventHandlerFactory.from_config(config=config)
        self.assertIsInstance(handler.channel, FileEventChannel)
        self.assertEqual(handler.channel.filename, "test.log")

    def test_factory_from_config_http(self):
        config = {"EVENTBUS_CHANNEL": "http", "EVENTBUS_HTTP_ENDPOINT": "http://example.com/events"}
        handler = EventHandlerFactory.from_config(config=config)
        self.assertIsInstance(handler.channel, HttpEventChannel)
        self.assertEqual(handler.channel.endpoint, "http://example.com/events")

    def test_factory_invalid_channel(self):
        invalid_config = {"EVENTBUS_CHANNEL": "unsupported"}
        with self.assertRaises(ValueError) as context:
            EventHandlerFactory.from_config(invalid_config)
        self.assertEqual(str(context.exception), "Unsupported channel type: unsupported")

    def test_factory_custom_channel(self):
        class CustomEventChannel(EventChannel):
            @classmethod
            def from_config(cls, config: Dict[str, str]):
                return cls()

            def send(self, event: Event) -> None:
                pass

        EventHandlerFactory.register_channel("custom", CustomEventChannel)
        config = {"EVENTBUS_CHANNEL": "custom"}
        handler = EventHandlerFactory.from_config(config=config)
        self.assertIsInstance(handler.channel, CustomEventChannel)
