"""In-memory transport for testing and single-process message dispatching."""

import asyncio
import queue
import threading

from ...core.basekurier import BaseKurier
from ...core.bus_types import BusType
from ...core.station import Station
from ...hermes import Hermes
from ...utilities.serializers import Serializer


class InMemoryLine(BaseKurier):
    """
    An in-memory Kurier line, designed for testing
    and simple, single-process passenger dispatching.
    Passengers are stored in a queue and processed by a dedicated thread.
    """

    bus_type = BusType.IN_MEMORY

    def __init__(self, name: str = "in_memory_instance_line", serializer: Serializer | None = None):
        super().__init__(name, serializer=serializer)
        self._message_queue = queue.Queue()
        self._running = True

        self._consumer_thread = threading.Thread(target=self._run_consumer_loop)
        self._consumer_thread.daemon = True
        self._consumer_thread.start()
        self._register()

    def _publish_to_bus(self, json_message: str, _):
        self._message_queue.put(json_message)

    def _run_consumer_loop(self):
        """
        The main loop for the consumer thread.
        It continuously retrieves passengers from the queue and dispatches them
        using the Station.
        """

        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        while self._running:
            try:
                envelope_str = self._message_queue.get(timeout=0.1)
                loop.run_until_complete(Station.dispatch(self, envelope_str))
                self._message_queue.task_done()

            except queue.Empty:
                pass

            except Exception as e:
                Hermes.fatal(f"InMemoryLine: Error during passenger consumption: {e}")

        loop.close()
        Hermes.info("InMemoryLine consumer loop stopped and asyncio loop closed.")

    @classmethod
    def start_consumer(cls, name: str) -> bool:
        """No-op for InMemoryLine — the consumer thread starts automatically in ``__init__``."""
        return True

    @classmethod
    def get(cls, _) -> "InMemoryLine":
        """Create and return a new ``InMemoryLine`` instance."""
        return cls()

    async def close(self):
        """
        Gracefully closes the InMemoryLine.
        Signals the consumer thread to stop and waits for it to finish.
        """
        Hermes.info("InMemoryLine: Initiating shutdown...")
        self._running = False

        if self._consumer_thread.is_alive():
            self._consumer_thread.join(timeout=5)

            if self._consumer_thread.is_alive():
                Hermes.warn("InMemoryLine: Consumer thread did not terminate gracefully within timeout.")

        Hermes.info("InMemoryLine: Closed.")
