using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;

namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring;

/// <summary>
/// Interface for central-side health aggregation.
/// Consumed by Central UI to display site health dashboards.
/// </summary>
public interface ICentralHealthAggregator
{
    /// <summary>
    /// Processes an incoming health report from a site and updates the aggregated state.
    /// </summary>
    /// <param name="report">The health report received from the site.</param>
    void ProcessReport(SiteHealthReport report);

    /// <summary>
    /// Bumps the last-seen timestamp for a site, keeping it marked online
    /// between full 30s reports when heartbeats are arriving — protects against
    /// the offline threshold firing on a transiently delayed report. Heartbeat
    /// cadence is owned by the Cluster Infrastructure / <c>SiteCommunicationActor</c>
    /// (the application-level heartbeat to central, sent every
    /// <c>CommunicationOptions.TransportHeartbeatInterval</c> — 5s by default);
    /// the 60s <see cref="HealthMonitoringOptions.OfflineTimeout"/> therefore
    /// tolerates several missed heartbeats. A heartbeat for a site with no
    /// aggregator state yet (e.g. just after a central restart/failover)
    /// registers that site as online with no
    /// <see cref="SiteHealthState.LatestReport"/>, so reachable sites are not
    /// shown as "unknown" during the failover window.
    /// </summary>
    /// <param name="siteId">The string identifier of the site that sent the heartbeat.</param>
    /// <param name="receivedAt">The UTC timestamp when the heartbeat was received.</param>
    void MarkHeartbeat(string siteId, DateTimeOffset receivedAt);

    /// <summary>Returns a snapshot of all currently tracked site health states.</summary>
    /// <returns>A dictionary mapping site id to its current <see cref="SiteHealthState"/>.</returns>
    IReadOnlyDictionary<string, SiteHealthState> GetAllSiteStates();
    /// <summary>Returns the current health state for the specified site, or null if not tracked.</summary>
    /// <param name="siteId">The string identifier of the site to look up.</param>
    /// <returns>The <see cref="SiteHealthState"/> for the site, or null if not yet seen.</returns>
    SiteHealthState? GetSiteState(string siteId);

    /// <summary>
    /// Removes tracked sites not in <paramref name="knownSiteIds"/> (i.e. deleted
    /// from configuration). The synthetic central id is always retained.
    /// Self-healing: called from the CentralCommunicationActor's periodic site
    /// refresh, so a deleted site disappears within one refresh interval without
    /// needing a dedicated deletion event. Without this the in-memory state only
    /// ever grew, leaving a deleted site as a permanently-offline dashboard tile
    /// (and a live KPI sample source) forever.
    /// </summary>
    /// <param name="knownSiteIds">The identifiers of all currently-configured sites.</param>
    void PruneUnknownSites(IReadOnlyCollection<string> knownSiteIds);
}
