<?php

declare(strict_types=1);

namespace Blax\WebRtc\Contracts;

use Blax\WebRtc\Rooms\RoomManager;
use Blax\WebRtc\Rooms\Stores\ArrayRoomStore;

/**
 * Where room membership + presence lives. The default {@see ArrayRoomStore}
 * keeps it in process memory, which is right for the long-lived bundled server
 * (one process owns every connection). A fork-per-message host (e.g. a classic
 * Laravel WebSocket that handles each frame in a fresh worker) has no shared
 * memory across messages, so it binds a store backed by Cache/Redis instead —
 * that is how learn-atc runs the relay on its existing WS without this package's
 * ReactPHP server.
 *
 * Peers keep exactly one room (joining a new one leaves the old). `add`/`remove`
 * must also maintain the peer→room reverse index that {@see roomOf} reads.
 */
interface RoomStore
{
    /**
     * Ordered peer ids currently in the room (insertion order).
     *
     * @return array<int,string>
     */
    public function members(string $roomId): array;

    /**
     * Presence info a peer published on join (empty array if none / not a presence room).
     *
     * @return array<string,mixed>
     */
    public function info(string $roomId, string $peerId): array;

    /** The room a peer is currently in, or null. */
    public function roomOf(string $peerId): ?string;

    /**
     * Add/update a peer (with presence info) in a room and set its reverse index.
     *
     * @param  array<string,mixed>  $info
     */
    public function add(string $roomId, string $peerId, array $info): void;

    /** Remove a peer from a room, clear its reverse index, and drop the room if it empties. */
    public function remove(string $roomId, string $peerId): void;

    /**
     * All non-empty room ids. Best-effort: a store that can't enumerate (e.g. a bare
     * Cache backend) may return an empty array — only {@see RoomManager::count()} relies on it.
     *
     * @return array<int,string>
     */
    public function roomIds(): array;
}
