namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
///
/// Wrapper that defers to an inner sink swapped in at
/// runtime. Needed because the production sink (SdkAddressSpaceSink) wraps an
/// OtOpcUaNodeManager that only exists after the SDK StandardServer has
/// started — but Akka actors resolve their sink dependency at construction time, before
/// the hosted service has booted the SDK.
///
/// Bound as a singleton in DI on driver-role hosts; the OPC UA hosted service calls
/// once the server is up. Until that swap happens, every call is a
/// no-op against , so the actor stays safe to
/// receive messages from the moment it boots.
///
public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink
{
private volatile IOpcUaAddressSpaceSink _inner = NullOpcUaAddressSpaceSink.Instance;
/// Swap in the production sink. Pass null to revert to the null sink
/// (used during graceful shutdown so post-stop writes don't hit a half-disposed manager).
public void SetSink(IOpcUaAddressSpaceSink? sink) =>
_inner = sink ?? NullOpcUaAddressSpaceSink.Instance;
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc)
=> _inner.WriteValue(nodeId, value, quality, sourceTimestampUtc);
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
=> _inner.WriteAlarmState(alarmNodeId, active, acknowledged, sourceTimestampUtc);
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
=> _inner.EnsureFolder(folderNodeId, parentNodeId, displayName);
public void RebuildAddressSpace() => _inner.RebuildAddressSpace();
}