from __future__ import annotations

from .bus_command_handler import ResponseStream
from ..errors import AdapterError


class RequestHandler:
    def feed(self, request: "Request", adapter: "Adapter") -> ResponseStream:
        if request.is_adapter_command:
            handler = None
            for command_set in adapter.command_sets:
                if command_set.can_handle(request.command):
                    handler = command_set
                    break
            if handler is None:
                raise AdapterError.invalid_command()
            stream = ResponseStream()
            try:
                handler.handle(request.command, adapter, stream.yield_output)
            except Exception as exc:
                stream.finish(error=exc)
                return stream
            stream.finish()
            return stream
        if request.is_bus_command:
            if not adapter.bus:
                raise AdapterError.no_data()
            if adapter.bitrate == 0:
                raise AdapterError.bus_init_error()
            adapter.bus.operate(adapter.bitrate)
            adapter.active_request = request
            if request.bus_command_handler is None:
                raise RuntimeError("Missing bus command handler")
            return request.bus_command_handler.handle(request.bus_bytes, adapter)
        raise AdapterError.invalid_command()
