from __future__ import annotations

import abc
from typing import Generic

from waku.messaging.contracts.message import ResponseT
from waku.messaging.contracts.request import RequestT

__all__ = [
    'RequestHandler',
]


class RequestHandler(abc.ABC, Generic[RequestT, ResponseT]):
    """Abstract base class for request handlers (commands/queries).

    Command handler example::

        class JoinMeetingCommandHandler(RequestHandler[JoinMeetingCommand, None]):
            def __init__(self, meetings_api: MeetingAPIProtocol) -> None:
                self._meetings_api = meetings_api

            async def handle(self, request: JoinMeetingCommand, /) -> None:
                await self._meetings_api.join_user(request.user_id, request.meeting_id)

    Query handler example::

        class ReadMeetingQueryHandler(RequestHandler[ReadMeetingQuery, ReadMeetingQueryResult]):
            def __init__(self, meetings_api: MeetingAPIProtocol) -> None:
                self._meetings_api = meetings_api

            async def handle(self, request: ReadMeetingQuery, /) -> ReadMeetingQueryResult:
                link = await self._meetings_api.get_link(request.meeting_id)
                return ReadMeetingQueryResult(link=link, meeting_id=request.meeting_id)

    """

    @abc.abstractmethod
    async def handle(self, request: RequestT, /) -> ResponseT:
        raise NotImplementedError
