namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;

/// <summary>
///     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.
/// </summary>
/// <remarks>
///     Per <c>docs/v2/plan.md</c> §5a (LmxNodeManager reusability) — <c>DriverAttributeInfo</c>
///     replaces the v1 Galaxy-specific <c>GalaxyAttributeInfo</c> in the generic node-manager
///     so the same node-manager class works against every driver.
/// </remarks>
/// <param name="FullName">
///     Driver-side full reference for read/write addressing
///     (e.g. for Galaxy: <c>"DelmiaReceiver_001.DownloadPath"</c>).
/// </param>
/// <param name="DriverDataType">Driver-agnostic data type; maps to OPC UA built-in type at build time.</param>
/// <param name="IsArray">True when this attribute is a 1-D array.</param>
/// <param name="ArrayDim">Declared array length when <see cref="IsArray"/> is true; null otherwise.</param>
/// <param name="SecurityClass">Write-authorization tier for this attribute.</param>
/// <param name="IsHistorized">True when this attribute is expected to feed historian / HistoryRead.</param>
/// <param name="IsAlarm">
///     True when this attribute represents an alarm condition (Galaxy: has an
///     <c>AlarmExtension</c> primitive). The generic node-manager enriches the variable with an
///     OPC UA <c>AlarmConditionState</c> when true. Defaults to false so existing non-Galaxy
///     drivers aren't forced to flow a flag they don't produce.
/// </param>
/// <param name="WriteIdempotent">
///     True when a timed-out or failed write to this attribute is safe to replay. Per
///     <c>docs/v2/plan.md</c>, 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.
/// </param>
/// <param name="Source">
///     Discriminates which runtime subsystem owns this node's dispatch.
///     Defaults to <see cref="NodeSourceKind.Driver"/> so existing callers are unchanged.
/// </param>
/// <param name="VirtualTagId">
///     Set when <paramref name="Source"/> is <see cref="NodeSourceKind.Virtual"/> — stable
///     logical id the VirtualTagEngine addresses by. Null otherwise.
/// </param>
/// <param name="ScriptedAlarmId">
///     Set when <paramref name="Source"/> is <see cref="NodeSourceKind.ScriptedAlarm"/> —
///     stable logical id the ScriptedAlarmEngine addresses by. Null otherwise.
/// </param>
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);

/// <summary>
///     Discriminates which runtime subsystem owns this node's Read/Write/
///     Subscribe dispatch. <c>Driver</c> = a real IDriver capability surface;
///     <c>Virtual</c> = a Phase 7 <see cref="DriverAttributeInfo"/>.VirtualTagId'd tag
///     computed by the VirtualTagEngine; <c>ScriptedAlarm</c> = a scripted Part 9 alarm
///     materialized by the ScriptedAlarmEngine.
/// </summary>
public enum NodeSourceKind
{
    Driver = 0,
    Virtual = 1,
    ScriptedAlarm = 2,
}
