using System.Security.Claims;

namespace ZB.MOM.WW.MxGateway.Server.Dashboard;

/// <summary>
/// Decides whether a dashboard principal may observe one session's mirrored
/// event stream (SEC-25 / TST-15). Consulted at every subscribe seam: the
/// SignalR <c>EventsHub.SubscribeSession</c> join and the in-process
/// <c>IDashboardSessionEventSubscriber.Subscribe</c> used by the
/// session-details page.
/// </summary>
/// <remarks>
/// The dashboard authenticates LDAP users while sessions are owned by API keys —
/// two disjoint identity domains — so the bridge is the session <em>tag</em>: a
/// session inherits its owning key's tags, and a dashboard group grants tags via
/// <c>MxGateway:Dashboard:GroupToTag</c>. See
/// <c>docs/plans/2026-07-10-dashboard-session-acl-tst15.md</c>.
/// </remarks>
public interface IDashboardSessionAcl
{
    /// <summary>
    /// Returns whether <paramref name="principal"/> may observe the events of the
    /// session identified by <paramref name="sessionId"/>.
    /// </summary>
    /// <param name="principal">
    /// The dashboard caller. <see langword="null"/> is denied outright — there is no
    /// caller to grant tags to, so it never reaches the untagged-session branch and is
    /// refused even under <c>UntaggedSessionVisibility=AllViewers</c>. An
    /// unauthenticated or claim-less principal (the anonymous-localhost path included)
    /// is a Viewer holding an empty tag grant, which denies every tagged session but
    /// still follows that branch.
    /// </param>
    /// <param name="sessionId">Session id the caller wants to observe.</param>
    /// <returns><see langword="true"/> when the caller may observe the session; otherwise <see langword="false"/>.</returns>
    bool CanViewSession(ClaimsPrincipal? principal, string sessionId);
}
