namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
///
/// Reverse-path gateway for an inbound OPC UA operator write to a writable equipment-tag node.
/// The node manager calls fire-and-forget from its OnWriteValue handler
/// (which runs under the node-manager Lock, so the call MUST return promptly — it kicks off an
/// asynchronous route and the Task completes later) and uses the resolved
/// to self-correct the node on failure.
///
public interface IOpcUaNodeWriteGateway
{
/// Route a write of to the driver backing node
/// ; the returned task resolves with the device-write outcome.
/// The full ns-qualified node id being written (node.NodeId.ToString()).
/// The value the client wrote.
/// Which of the two v3 namespaces ( device tree or
/// equipment tree) lives in — the node
/// manager resolves it from the node's namespace index (RealmOf). It is REQUIRED for correct
/// routing: a raw s=<RawPath> and a UNS s=<Area/Line/Equip/Eff> can collide as bare
/// strings, so the routing map is keyed by (realm, bareId) — dropping the realm would let an
/// operator write route to the WRONG driver ref.
/// Cancellation token.
/// A task resolving to the device-write outcome.
Task WriteAsync(string nodeId, object? value, AddressSpaceRealm realm, CancellationToken ct);
}
/// Outcome of routing an inbound node write to the backing driver.
/// True when the driver accepted the write.
/// Failure detail when is false; null on success.
public readonly record struct NodeWriteOutcome(bool Success, string? Reason);
/// No-op gateway: every write resolves to "writes unavailable" (matches the legacy
/// no-router-wired BadNotWritable). The default before the host wires the real gateway.
public sealed class NullOpcUaNodeWriteGateway : IOpcUaNodeWriteGateway
{
/// The shared singleton instance.
public static readonly NullOpcUaNodeWriteGateway Instance = new();
private NullOpcUaNodeWriteGateway() { }
///
public Task WriteAsync(string nodeId, object? value, AddressSpaceRealm realm, CancellationToken ct) =>
Task.FromResult(new NodeWriteOutcome(false, "writes unavailable"));
}