namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
///
/// Driver-agnostic per-attribute (tag) descriptor used by the generic node-manager
/// to build OPC UA address-space variables. Every driver maps its native attribute
/// metadata into this DTO during discovery.
///
///
/// Per docs/v2/plan.md §5a (LmxNodeManager reusability) — DriverAttributeInfo
/// replaces the v1 Galaxy-specific GalaxyAttributeInfo in the generic node-manager
/// so the same node-manager class works against every driver.
///
///
/// Driver-side full reference for read/write addressing
/// (e.g. for Galaxy: "DelmiaReceiver_001.DownloadPath").
///
/// Driver-agnostic data type; maps to OPC UA built-in type at build time.
/// True when this attribute is a 1-D array.
/// Declared array length when is true; null otherwise.
/// Write-authorization tier for this attribute.
/// True when this attribute is expected to feed historian / HistoryRead.
///
/// True when this attribute represents an alarm condition (Galaxy: has an
/// AlarmExtension primitive). The generic node-manager enriches the variable with an
/// OPC UA AlarmConditionState when true. Defaults to false so existing non-Galaxy
/// drivers aren't forced to flow a flag they don't produce.
///
///
/// True when a timed-out or failed write to this attribute is safe to replay. Per
/// docs/v2/plan.md, writes are NOT auto-retried by default
/// because replaying a pulse / alarm-ack / counter-increment / recipe-step advance can
/// duplicate field actions. Drivers flag only tags whose semantics make retry safe
/// (holding registers with level-set values, set-point writes to analog tags) — the
/// capability invoker respects this flag when deciding whether to apply Polly retry.
///
///
/// Discriminates which runtime subsystem owns this node's dispatch.
/// Defaults to so existing callers are unchanged.
///
///
/// Set when is — stable
/// logical id the VirtualTagEngine addresses by. Null otherwise.
///
///
/// Set when is —
/// stable logical id the ScriptedAlarmEngine addresses by. Null otherwise.
///
///
/// The driver's OWN type name for this attribute (e.g. "Real" for an
/// AbCipDataType, "Int16" for a TwinCATDataType) when the driver binds
/// by a driver-specific type enum in its TagConfig; null for a driver whose tag config
/// carries no type (OPC UA Client, Galaxy) or which takes the type from the wire (MQTT
/// Sparkplug births, MTConnect probe inference).
///
/// It exists because is lossy in exactly the direction a
/// browse-commit needs (Gitea #536): AbCipDataType.SInt, .Int and .DInt
/// all map to , so a commit that reverse-mapped the
/// driver-agnostic type would bind a 16-bit INT as a 32-bit DINT. Nothing downstream of the
/// address-space build reads this — it is authoring metadata carried alongside the type the
/// node manager actually uses.
///
///
public sealed record DriverAttributeInfo(
string FullName,
DriverDataType DriverDataType,
bool IsArray,
uint? ArrayDim,
SecurityClassification SecurityClass,
bool IsHistorized,
bool IsAlarm = false,
bool WriteIdempotent = false,
NodeSourceKind Source = NodeSourceKind.Driver,
string? VirtualTagId = null,
string? ScriptedAlarmId = null,
string? NativeDataType = null);
///
/// Discriminates which runtime subsystem owns this node's Read/Write/
/// Subscribe dispatch. Driver = a real IDriver capability surface;
/// Virtual = a Phase 7 .VirtualTagId'd tag
/// computed by the VirtualTagEngine; ScriptedAlarm = a scripted Part 9 alarm
/// materialized by the ScriptedAlarmEngine.
///
public enum NodeSourceKind
{
Driver = 0,
Virtual = 1,
ScriptedAlarm = 2,
}