namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
///
/// Driver capability for invoking OPC UA Methods on the upstream backend (the OPC UA
/// Call service). Optional — only drivers whose backends carry method nodes
/// implement it. Currently the OPC UA Client driver is the only implementer; tag-based
/// drivers (Modbus, S7, FOCAS, Galaxy, AB-CIP, AB-Legacy, TwinCAT) don't expose method
/// nodes so they don't need this surface.
///
///
///
/// Per docs/v2/plan.md decision #4 (composable capability interfaces) — the
/// server-side DriverNodeManager discovers method-bearing drivers via an
/// is IMethodInvoker check and routes OnCallMethod handlers to
/// . Drivers that don't implement the interface simply
/// never have method nodes registered for them.
///
///
/// The address-space mirror is driven by
/// — drivers register the method node + its InputArguments /
/// OutputArguments properties during discovery, then invocations land back on
/// via the server-side dispatcher.
///
///
public interface IMethodInvoker
{
///
/// Invoke an upstream OPC UA Method. The driver translates input arguments into the
/// wire-level CallMethodRequest, dispatches via the active session, and packs
/// the response back into a . Per-argument validation
/// errors flow through ; method-level
/// errors (BadMethodInvalid, BadUserAccessDenied, etc.) flow through
/// .
///
///
/// Stringified NodeId of the OPC UA Object that owns the method (the ObjectId
/// field of CallMethodRequest). Same serialization as IReadable's
/// fullReference — ns=2;s=… / i=… / nsu=…;….
///
///
/// Stringified NodeId of the Method node itself (the MethodId field).
///
///
/// Input arguments in declaration order. The driver wraps each value as a
/// Variant; callers pass CLR primitives (plus arrays) — the wire-level
/// encoding is the driver's concern.
///
/// Per-call cancellation.
///
/// Result of the call — see . Never throws for a
/// Bad upstream status; the bad code is surfaced via the result so the caller
/// can map it onto an OPC UA service-result for downstream clients.
///
Task CallMethodAsync(
string objectNodeId,
string methodNodeId,
object[] inputs,
CancellationToken cancellationToken);
}
///
/// Result of a single OPC UA Call service invocation.
///
///
/// Method-level status. 0 = Good. Bad codes pass through verbatim from the
/// upstream so downstream clients see the canonical OPC UA error (e.g.
/// BadMethodInvalid, BadUserAccessDenied, BadArgumentsMissing).
///
///
/// Output argument values in declaration order. null when the upstream returned
/// no output arguments (or returned a Bad status before producing any).
///
///
/// Per-input-argument status codes. null when the upstream didn't surface
/// per-argument validation results (typical for Good calls). Each entry is the OPC UA
/// status code for the matching input argument — drivers can use this to surface
/// BadTypeMismatch, BadOutOfRange, etc. on a specific argument.
///
public sealed record MethodCallResult(
uint StatusCode,
object[]? Outputs,
uint[]? InputArgumentResults);