using ZB.MOM.WW.OtOpcUa.Configuration.Enums;

namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;

/// <summary>
///     One canonical tag (signal) in a cluster's generation. Per decision #110:
///     <see cref="EquipmentId"/> is REQUIRED when the driver is in an Equipment-kind namespace
///     and NULL when in SystemPlatform-kind namespace (Galaxy hierarchy preserved).
/// </summary>
public sealed class Tag
{
    /// <summary>
    /// Gets or sets the unique database row identifier for the tag.
    /// </summary>
    public Guid TagRowId { get; set; }

    /// <summary>
    /// Gets or sets the tag identifier.
    /// </summary>
    public required string TagId { get; set; }

    /// <summary>
    /// Gets or sets the driver instance identifier for this tag.
    /// </summary>
    public required string DriverInstanceId { get; set; }

    /// <summary>
    /// Gets or sets the device identifier.
    /// </summary>
    public string? DeviceId { get; set; }

    /// <summary>
    ///     Required when driver is in Equipment-kind namespace; NULL when in SystemPlatform-kind.
    ///     Cross-table invariant enforced by sp_ValidateDraft (decision #110).
    /// </summary>
    public string? EquipmentId { get; set; }

    /// <summary>
    /// Gets or sets the tag name.
    /// </summary>
    public required string Name { get; set; }

    /// <summary>Only used when <see cref="EquipmentId"/> is NULL (SystemPlatform namespace).</summary>
    public string? FolderPath { get; set; }

    /// <summary>OPC UA built-in type name (Boolean / Int32 / Float / etc.).</summary>
    public required string DataType { get; set; }

    /// <summary>
    /// Gets or sets the access level for this tag.
    /// </summary>
    public required TagAccessLevel AccessLevel { get; set; }

    /// <summary>Per decisions #44–45 — opt-in for write retry eligibility.</summary>
    public bool WriteIdempotent { get; set; }

    /// <summary>
    /// Gets or sets the poll group identifier for batching read/write operations.
    /// </summary>
    public string? PollGroupId { get; set; }

    /// <summary>Register address / scaling / poll group / byte-order / etc. — schemaless per driver type.</summary>
    public required string TagConfig { get; set; }

    /// <summary>Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.</summary>
    public byte[] RowVersion { get; set; } = Array.Empty<byte>();
}
