using System.Collections.Concurrent;
namespace ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms;
///
/// Persistence for across server restarts. Phase 7
/// plan decision #14: operator-supplied state (EnabledState / AckedState /
/// ConfirmedState / ShelvingState + audit trail) persists; ActiveState is
/// recomputed from the live predicate on startup so operators never re-ack.
///
///
/// Stream E wires this to a SQL-backed store against the ScriptedAlarmState
/// table with audit logging through IAuditLogger.
/// Tests + local dev use .
///
public interface IAlarmStateStore
{
Task LoadAsync(string alarmId, CancellationToken ct);
Task> LoadAllAsync(CancellationToken ct);
Task SaveAsync(AlarmConditionState state, CancellationToken ct);
Task RemoveAsync(string alarmId, CancellationToken ct);
}
/// In-memory default — used by tests + by dev deployments without a SQL backend.
public sealed class InMemoryAlarmStateStore : IAlarmStateStore
{
private readonly ConcurrentDictionary _map
= new(StringComparer.Ordinal);
public Task LoadAsync(string alarmId, CancellationToken ct)
=> Task.FromResult(_map.TryGetValue(alarmId, out var v) ? v : null);
public Task> LoadAllAsync(CancellationToken ct)
=> Task.FromResult>(_map.Values.ToArray());
public Task SaveAsync(AlarmConditionState state, CancellationToken ct)
{
_map[state.AlarmId] = state;
return Task.CompletedTask;
}
public Task RemoveAsync(string alarmId, CancellationToken ct)
{
_map.TryRemove(alarmId, out _);
return Task.CompletedTask;
}
}