"""In-memory registry of connected gossip peers."""

from __future__ import annotations

import threading
import time
from dataclasses import dataclass, field
from typing import Any


@dataclass
class PeerEntry:
    peer_id: str
    addr: str
    ws: Any  # websockets.WebSocketServerProtocol
    connected_at: float = field(default_factory=time.monotonic)
    last_seen: float = field(default_factory=time.monotonic)


class PeerRegistry:
    def __init__(self):
        self._peers: dict[str, PeerEntry] = {}
        self._lock = threading.Lock()

    def register(self, peer_id: str, addr: str, ws) -> None:
        with self._lock:
            self._peers[peer_id] = PeerEntry(peer_id=peer_id, addr=addr, ws=ws)

    def unregister(self, peer_id: str) -> None:
        with self._lock:
            self._peers.pop(peer_id, None)

    def touch(self, peer_id: str) -> None:
        with self._lock:
            if peer_id in self._peers:
                self._peers[peer_id].last_seen = time.monotonic()

    def get(self, peer_id: str) -> PeerEntry | None:
        with self._lock:
            return self._peers.get(peer_id)

    def all_except(self, peer_id: str) -> list[PeerEntry]:
        with self._lock:
            return [e for pid, e in self._peers.items() if pid != peer_id]

    def list_peers(self) -> list[dict]:
        with self._lock:
            return [
                {
                    "peer_id": e.peer_id,
                    "addr": e.addr,
                    "connected_at": e.connected_at,
                    "last_seen": e.last_seen,
                }
                for e in self._peers.values()
            ]

    def __len__(self) -> int:
        with self._lock:
            return len(self._peers)
