using System.Collections.Concurrent;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;

namespace ZB.MOM.WW.OtOpcUa.AdminUI.Hubs;

/// <summary>
///     Thread-safe in-memory implementation of <see cref="IDriverResilienceStatusStore"/>.
///     Keyed by <c>(DriverInstanceId, HostName)</c>; last write wins.
/// </summary>
public sealed class InMemoryDriverResilienceStatusStore : IDriverResilienceStatusStore
{
    private readonly ConcurrentDictionary<(string Instance, string Host), DriverResilienceStatusChanged> _byPair = new();

    /// <inheritdoc />
    public event Action<DriverResilienceStatusChanged>? SnapshotChanged;

    /// <inheritdoc />
    public void Upsert(DriverResilienceStatusChanged snapshot)
    {
        _byPair[(snapshot.DriverInstanceId, snapshot.HostName)] = snapshot;
        // Capture-then-invoke so a concurrent unsubscribe can't null the delegate mid-raise.
        SnapshotChanged?.Invoke(snapshot);
    }

    /// <inheritdoc />
    public IReadOnlyList<DriverResilienceStatusChanged> GetForInstance(string driverInstanceId) =>
        _byPair.Values
            .Where(s => string.Equals(s.DriverInstanceId, driverInstanceId, StringComparison.Ordinal))
            .ToList();

    /// <inheritdoc />
    public IReadOnlyCollection<DriverResilienceStatusChanged> GetAll() => _byPair.Values.ToArray();
}
