using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using ZB.MOM.WW.MxGateway.Contracts.Proto;

namespace ZB.MOM.WW.MxGateway.Server.Sessions;

/// <summary>
/// Thread-safe registry of active gateway sessions.
/// </summary>
public sealed class SessionRegistry : ISessionRegistry
{
    private readonly ConcurrentDictionary<string, GatewaySession> _sessions = new(StringComparer.Ordinal);

    /// <inheritdoc />
    public int Count => _sessions.Count;

    /// <inheritdoc />
    public int ActiveCount => _sessions.Values.Count(session => session.State is not SessionState.Closed);

    /// <inheritdoc />
    public bool TryAdd(GatewaySession session)
    {
        ArgumentNullException.ThrowIfNull(session);

        return _sessions.TryAdd(session.SessionId, session);
    }

    /// <inheritdoc />
    public bool TryGet(
        string sessionId,
        [MaybeNullWhen(false)] out GatewaySession session)
    {
        return _sessions.TryGetValue(sessionId, out session);
    }

    /// <inheritdoc />
    public bool TryRemove(
        string sessionId,
        [MaybeNullWhen(false)] out GatewaySession session)
    {
        return _sessions.TryRemove(sessionId, out session);
    }

    /// <inheritdoc />
    public IReadOnlyCollection<GatewaySession> Snapshot()
    {
        return _sessions.Values.ToArray();
    }
}
