using ZB.MOM.WW.OtOpcUa.Commons.Types;

namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces;

/// <summary>
/// Live view of the local node's identity and the cluster's role topology. Implemented by
/// <c>ClusterRoleInfo</c> in <c>OtOpcUa.Cluster</c>; consumed by everything that needs to
/// distinguish admin-role vs driver-role members or react to role-leader changes (e.g. OPC UA
/// ServiceLevel computation).
/// </summary>
public interface IClusterRoleInfo
{
    /// <summary>Gets the local cluster node identifier.</summary>
    NodeId LocalNode { get; }
    /// <summary>Gets the set of roles assigned to the local node.</summary>
    IReadOnlySet<string> LocalRoles { get; }
    /// <summary>Checks if the local node has the specified role.</summary>
    /// <param name="role">Role name to check.</param>
    /// <returns>True if the local node has the role; otherwise, false.</returns>
    bool HasRole(string role);
    /// <summary>Gets all nodes assigned to the specified role.</summary>
    /// <param name="role">Role name to query.</param>
    /// <returns>List of node identifiers with the role.</returns>
    IReadOnlyList<NodeId> MembersWithRole(string role);
    /// <summary>Gets the leader node for the specified role, or null if no leader is elected.</summary>
    /// <param name="role">Role name to query.</param>
    /// <returns>The leader node identifier, or null if no leader exists.</returns>
    NodeId? RoleLeader(string role);

    /// <summary>Occurs when the leader of a role changes.</summary>
    event EventHandler<RoleLeaderChangedEventArgs>? RoleLeaderChanged;
}
