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

/// <summary>
///     Supplies the Browse and Alarms dashboard tabs with live MXAccess data.
///     Owns one shared, lazily-opened gateway session (and therefore one
///     worker process) used by every dashboard circuit; the session is
///     transparently re-opened if it faults or its lease expires.
/// </summary>
public interface IDashboardLiveDataService
{
    /// <summary>
    ///     Subscribes (once) and reads the current value, quality and timestamp
    ///     of the supplied tags. Never throws — transport and session failures
    ///     are surfaced in <see cref="DashboardLiveReadResult.Error"/>.
    /// </summary>
    /// <param name="tagAddresses">Fully-qualified tag references to read.</param>
    /// <param name="cancellationToken">Token to cancel the read.</param>
    /// <returns>The read result, or an error-bearing result on failure.</returns>
    Task<DashboardLiveReadResult> ReadAsync(
        IReadOnlyCollection<string> tagAddresses,
        CancellationToken cancellationToken);

    /// <summary>
    ///     Queries the currently-active alarm set for the dashboard session.
    ///     Never throws — failures are surfaced in
    ///     <see cref="DashboardAlarmQueryResult.Error"/>.
    /// </summary>
    /// <param name="cancellationToken">Token to cancel the query.</param>
    /// <returns>The active alarms, or an error-bearing result on failure.</returns>
    Task<DashboardAlarmQueryResult> QueryAlarmsAsync(CancellationToken cancellationToken);
}

/// <summary>Result of a dashboard live tag read.</summary>
/// <param name="Values">The per-tag values, or an empty list on error.</param>
/// <param name="Error">A diagnostic message when the read failed; otherwise null.</param>
/// <param name="SessionId">The dashboard session id used, when available.</param>
/// <param name="WorkerProcessId">The worker process id backing the session, when available.</param>
public sealed record DashboardLiveReadResult(
    IReadOnlyList<DashboardTagValue> Values,
    string? Error,
    string? SessionId,
    int? WorkerProcessId)
{
    /// <summary>An empty, successful result — used when no tags are subscribed.</summary>
    public static DashboardLiveReadResult Empty { get; } =
        new([], null, null, null);
}
