using Akka.Cluster;
using ZB.MOM.WW.Health.Akka;

namespace ZB.MOM.WW.ScadaBridge.Host.Health;

/// <summary>
/// THE single definition of "active node" (review 01 [High]): a node is active
/// when it is the OLDEST Up member (optionally within a role scope) — i.e. the
/// member the ClusterSingletonManager places singletons on. Cluster LEADERSHIP
/// (lowest address) is an Akka-internal concept that diverges from singleton
/// placement permanently once the original first node restarts and rejoins;
/// every product-level active/standby decision must use this evaluator, never
/// cluster.State.Leader.
/// </summary>
public static class ClusterActivityEvaluator
{
    /// <summary>True when self is Up and no other Up member (in the role scope) is older.
    /// Delegates to the shared <see cref="Communication.ClusterState.ActiveNodeEvaluator"/> —
    /// one implementation for the delivery gate, the resync authority checks, and the
    /// heartbeat IsActive stamp (review 02 round 2, N1).</summary>
    /// <param name="cluster">The Akka cluster to evaluate.</param>
    /// <param name="role">Optional role scope; when set, only members with this role are considered.</param>
    /// <returns><c>true</c> when self is Up and the oldest Up member in the role scope.</returns>
    public static bool SelfIsOldest(Cluster cluster, string? role = null) =>
        Communication.ClusterState.ActiveNodeEvaluator.SelfIsOldestUp(cluster, role);

    /// <summary>The oldest Up member in the role scope, or null while none is Up. Used for Primary/Standby labelling.</summary>
    /// <param name="cluster">The Akka cluster to evaluate.</param>
    /// <param name="role">Optional role scope; when set, only members with this role are considered.</param>
    /// <returns>The oldest Up member in the role scope, or null when none is Up.</returns>
    /// <remarks>
    /// Delegates to the shared <see cref="ClusterActiveNode.OldestUpMember(Cluster, string?)"/>, so
    /// the label a node shows and the answer <see cref="SelfIsOldest"/> gates on come from one rule.
    /// </remarks>
    public static Member? OldestUpMember(Cluster cluster, string? role = null) =>
        ClusterActiveNode.OldestUpMember(cluster, role);
}
