using System.Collections.Concurrent;
namespace SameBeat.Api.Monitoring;
///
/// Prosty licznik otwartych polaczen SignalR, trzymany w pamieci procesu (ETAP 8). Wystarczajacy dla
/// MVP jednej instancji backendu -- NIE jest to licznik rozproszony: przy kilku instancjach API za
/// load balancerem kazda miaĆaby wlasny, czesciowy stan. Rozproszony licznik (np. przez Redis) jest
/// poza zakresem MVP.
///
/// Kazde polaczenie SignalR trafia od razu do grupy "widzowie" w StanImprezyHub.OnConnectedAsync i --
/// na dzien dzisiejszy -- nigdy z niej nie jest usuwane, wiec licznik ogolny pokrywa sie z licznikiem
/// widzow. Grupa "host" jest podzbiorem: polaczenie dolacza do niej wylacznie przez wywolanie
/// DolaczDoGrupyHosta (po pozytywnej autoryzacji [Authorize] na tej metodzie).
///
/// Watkowo bezpieczne dzieki ConcurrentDictionary -- SignalR moze wywolywac OnConnectedAsync/
/// OnDisconnectedAsync dla wielu polaczen rownolegle.
///
public sealed class LicznikPolaczenSignalR
{
private readonly ConcurrentDictionary _polaczenia = new();
private readonly ConcurrentDictionary _polaczeniaHost = new();
/// Rejestruje nowe polaczenie (kazde polaczenie automatycznie trafia do grupy "widzowie").
public void Polaczono(string idPolaczenia) => _polaczenia[idPolaczenia] = 0;
/// Rejestruje dolaczenie polaczenia do grupy "host" (po autoryzacji hosta).
public void DolaczylDoGrupyHosta(string idPolaczenia) => _polaczeniaHost[idPolaczenia] = 0;
/// Usuwa polaczenie ze wszystkich sledzonych grup -- wywolywane przy rozlaczeniu.
public void Rozlaczono(string idPolaczenia)
{
_polaczenia.TryRemove(idPolaczenia, out _);
_polaczeniaHost.TryRemove(idPolaczenia, out _);
}
/// Liczba wszystkich aktualnie otwartych polaczen SignalR (uzywane w /api/health).
public int LiczbaPolaczenOgolem => _polaczenia.Count;
/// Liczba polaczen w grupie "widzowie" -- dzis rowna liczbie ogolem, patrz komentarz klasy.
public int LiczbaPolaczenWidzowie => _polaczenia.Count;
/// Liczba polaczen w grupie "host".
public int LiczbaPolaczenHost => _polaczeniaHost.Count;
}