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

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

/// <summary>
///     Per-host connectivity snapshot the Server publishes for each driver's
///     <c>IHostConnectivityProbe.GetHostStatuses</c> entry. One row per
///     (<see cref="NodeId"/>, <see cref="DriverInstanceId"/>, <see cref="HostName"/>) triple —
///     a redundant 2-node cluster with one Galaxy driver reporting 3 platforms produces 6
///     rows, not 3, because each server node owns its own runtime view.
/// </summary>
/// <remarks>
///     <para>
///         Supports the per-AppEngine Admin dashboard drill-down. The publisher hosted
///         service on the Server side subscribes to every
///         registered driver's <c>OnHostStatusChanged</c> and upserts rows on transitions +
///         periodic liveness heartbeats. <see cref="LastSeenUtc"/> advances on every
///         heartbeat so the Admin UI can flag stale rows from a crashed Server.
///     </para>
///     <para>
///         No foreign-key to <see cref="ClusterNode"/> — a Server may start reporting host
///         status before its ClusterNode row exists (e.g. first-boot bootstrap), and we'd
///         rather keep the status row than drop it. The Admin-side service left-joins on
///         NodeId when presenting rows.
///     </para>
/// </remarks>
public sealed class DriverHostStatus
{
    /// <summary>Server node that's running the driver.</summary>
    public required string NodeId { get; set; }

    /// <summary>Driver instance's stable id (matches <c>IDriver.DriverInstanceId</c>).</summary>
    public required string DriverInstanceId { get; set; }

    /// <summary>
    ///     Driver-side host identifier — Galaxy Platform / AppEngine name, Modbus
    ///     <c>host:port</c>, whatever the probe returns. Opaque to the Admin UI except as
    ///     a display string.
    /// </summary>
    public required string HostName { get; set; }

    /// <summary>Gets or sets the current connectivity state of the host.</summary>
    public DriverHostState State { get; set; } = DriverHostState.Unknown;

    /// <summary>Timestamp of the last state transition (not of the most recent heartbeat).</summary>
    public DateTime StateChangedUtc { get; set; }

    /// <summary>
    ///     Advances on every publisher heartbeat — the Admin UI uses
    ///     <c>now - LastSeenUtc &gt; threshold</c> to flag rows whose owning Server has
    ///     stopped reporting (crashed, network-partitioned, etc.), independent of
    ///     <see cref="State"/>.
    /// </summary>
    public DateTime LastSeenUtc { get; set; }

    /// <summary>
    ///     Optional human-readable detail populated when <see cref="State"/> is
    ///     <see cref="DriverHostState.Faulted"/> — e.g. the exception message from the
    ///     driver's probe. Null for Running / Stopped / Unknown transitions.
    /// </summary>
    public string? Detail { get; set; }
}
