from multiprocessing import Pipe
from multiprocessing.connection import Connection

from typing import TypeVar, Generic, Type, Optional, Tuple

SendT = TypeVar("SendT")
RecvT = TypeVar("RecvT")
T = TypeVar("T")

class SingleSendPipe(Generic[SendT]):
    def __init__(self, send_type: Type[SendT], connection: Connection):            
        self._connection = connection

    def send(self, data: SendT):
        self._connection.send(data)
        self._connection.close()
    
    def close(self) -> None:
        self._connection.close()


class SingleRecvPipe(Generic[RecvT]):
    def __init__(self, recv_type: Type[RecvT], connection: Connection):            
        self._connection = connection

    def recv(self) -> RecvT:
        data = self._connection.recv()
        self._connection.close()
        return data
    
    def close(self) -> None:
        self._connection.close()

    def poll(self, timeout: Optional[float] = None):
        return self._connection.poll(timeout=timeout)

    @property
    def closed(self) -> bool:
        return self._connection.closed


def make_single_return_pipes(
    send_type: Type[SendT],
) -> Tuple[SingleSendPipe[SendT], SingleRecvPipe[SendT]]:
    c1, c2 = Pipe(duplex=False)
    return SingleSendPipe(send_type, c2), SingleRecvPipe(send_type, c1)