"""Abstract transport layer."""

from __future__ import annotations

from abc import ABC, abstractmethod
from collections.abc import AsyncIterator


class Connection(ABC):
    """Authenticated encrypted bidirectional channel to a peer."""

    @property
    @abstractmethod
    def peer_id(self) -> str: ...

    @property
    @abstractmethod
    def remote_addr(self) -> str: ...

    @property
    @abstractmethod
    def is_open(self) -> bool: ...

    @abstractmethod
    async def send(self, data: bytes) -> None: ...

    @abstractmethod
    async def recv(self) -> bytes: ...

    @abstractmethod
    async def close(self) -> None: ...


class Transport(ABC):
    """Listens for inbound and initiates outbound connections."""

    @abstractmethod
    async def listen(self, host: str, port: int) -> AsyncIterator[Connection]: ...

    @abstractmethod
    async def connect(self, addr: str) -> Connection: ...

    @abstractmethod
    async def shutdown(self) -> None: ...
