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

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

/// <summary>
///     Inputs for draft validation. Contains the draft's rows plus the minimum prior-generation
///     rows needed for cross-generation invariants (EquipmentUuid stability, UnsArea identity).
/// </summary>
public sealed class DraftSnapshot
{
    /// <summary>Gets the draft generation identifier.</summary>
    public required long GenerationId { get; init; }
    /// <summary>Gets the cluster identifier.</summary>
    public required string ClusterId { get; init; }

    /// <summary>
    ///     Cluster's Enterprise segment (UNS level 1). When set, <see cref="DraftValidator"/> uses
    ///     the actual length for path-length checks instead of a conservative 32-char upper bound.
    /// </summary>
    public string? Enterprise { get; init; }

    /// <summary>
    ///     Cluster's Site segment (UNS level 2). When set, <see cref="DraftValidator"/> uses the
    ///     actual length for path-length checks instead of a conservative 32-char upper bound.
    /// </summary>
    public string? Site { get; init; }

    // v3: the Namespace entity is retired (the two OPC UA namespaces are implicit). The Raw tree
    // (RawFolders → DriverInstances → Devices → TagGroups → Tags) + the UNS projection
    // (UnsTagReferences) feed the v3 validator rules (raw-name charset, historized-tagname length, UNS
    // effective-leaf uniqueness).
    /// <summary>Gets the list of Raw-tree folders (drive the raw-name charset rule + RawPath computation).</summary>
    public IReadOnlyList<RawFolder> RawFolders { get; init; } = [];
    /// <summary>Gets the list of driver instances.</summary>
    public IReadOnlyList<DriverInstance> DriverInstances { get; init; } = [];
    /// <summary>Gets the list of devices.</summary>
    public IReadOnlyList<Device> Devices { get; init; } = [];
    /// <summary>Gets the list of tag-groups (drive the raw-name charset rule + RawPath computation).</summary>
    public IReadOnlyList<TagGroup> TagGroups { get; init; } = [];
    /// <summary>Gets the list of UNS areas.</summary>
    public IReadOnlyList<UnsArea> UnsAreas { get; init; } = [];
    /// <summary>Gets the list of UNS lines.</summary>
    public IReadOnlyList<UnsLine> UnsLines { get; init; } = [];
    /// <summary>Gets the list of equipment.</summary>
    public IReadOnlyList<Equipment> Equipment { get; init; } = [];
    /// <summary>Gets the list of raw tags.</summary>
    public IReadOnlyList<Tag> Tags { get; init; } = [];

    /// <summary>Gets the UNS tag references (raw tag → equipment projection). Drives the UNS effective-leaf
    /// uniqueness rule (effective name = DisplayNameOverride else the backing raw tag's Name).</summary>
    public IReadOnlyList<UnsTagReference> UnsTagReferences { get; init; } = [];

    /// <summary>Equipment-bound VirtualTags (script-derived signals). Part of the UNS effective-leaf
    /// uniqueness set within an equipment (references + VirtualTags + ScriptedAlarms).</summary>
    public IReadOnlyList<VirtualTag> VirtualTags { get; init; } = [];
    /// <summary>Equipment-bound scripted alarms. Part of the UNS effective-leaf uniqueness set.</summary>
    public IReadOnlyList<ScriptedAlarm> ScriptedAlarms { get; init; } = [];

    /// <summary>User-authored scripts (shared by VirtualTags, ScriptedAlarms, and Calculation tags). Drives
    /// the WP7 Calculation gates: <c>scriptId</c> existence + the calc→calc dependency-cycle check.</summary>
    public IReadOnlyList<Script> Scripts { get; init; } = [];
    /// <summary>Gets the list of poll groups.</summary>
    public IReadOnlyList<PollGroup> PollGroups { get; init; } = [];

    /// <summary>Prior Equipment rows (any generation, same cluster) for stability checks.</summary>
    public IReadOnlyList<Equipment> PriorEquipment { get; init; } = [];

    /// <summary>Active reservations (<c>ReleasedAt IS NULL</c>) for pre-flight.</summary>
    public IReadOnlyList<ExternalIdReservation> ActiveReservations { get; init; } = [];
}
