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="IDriverStatusSnapshotStore"/>.
///     Keyed by <see cref="DriverHealthChanged.DriverInstanceId"/>; last write wins.
/// </summary>
public sealed class InMemoryDriverStatusSnapshotStore : IDriverStatusSnapshotStore
{
    private readonly ConcurrentDictionary<string, DriverHealthChanged> _byInstance = new();

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

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

    /// <inheritdoc />
    public bool TryGet(string driverInstanceId, out DriverHealthChanged snapshot)
        => _byInstance.TryGetValue(driverInstanceId, out snapshot!);

    /// <inheritdoc />
    public IReadOnlyCollection<DriverHealthChanged> GetAll() => _byInstance.Values.ToArray();
}
