using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;

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

public record SiteHealthReport(
    string SiteId,
    long SequenceNumber,
    DateTimeOffset ReportTimestamp,
    IReadOnlyDictionary<string, ConnectionHealth> DataConnectionStatuses,
    IReadOnlyDictionary<string, TagResolutionStatus> TagResolutionCounts,
    int ScriptErrorCount,
    int AlarmEvaluationErrorCount,
    IReadOnlyDictionary<string, int> StoreAndForwardBufferDepths,
    int DeadLetterCount,
    int DeployedInstanceCount,
    int EnabledInstanceCount,
    int DisabledInstanceCount,
    string NodeRole = "Unknown",
    string NodeHostname = "",
    IReadOnlyDictionary<string, string>? DataConnectionEndpoints = null,
    IReadOnlyDictionary<string, TagQualityCounts>? DataConnectionTagQuality = null,
    int ParkedMessageCount = 0,
    IReadOnlyList<NodeStatus>? ClusterNodes = null,
    // Audit Log (#23) M2 Bundle G: per-interval count of FallbackAuditWriter
    // primary failures (SQLite throws routed to the drop-oldest ring). Surfaces
    // a sustained audit-write outage on /monitoring/health. Defaults to 0 so
    // existing producers / tests that don't construct the field stay valid.
    int SiteAuditWriteFailures = 0,
    // Audit Log (#23) M5 Bundle C: per-interval count of payload-filter
    // redactor over-redactions (header / body / SQL parameter stages all
    // throwing → field replaced with the "<redacted: redactor error>"
    // marker). Surfaces a misconfigured / catastrophic regex on
    // /monitoring/health. Defaults to 0 for back-compat with existing
    // producers and tests that don't construct the field.
    int AuditRedactionFailure = 0,
    // Audit Log (#23) M6 Bundle E (T6): point-in-time snapshot of the
    // site-local SQLite audit-log queue (pending count, oldest pending row,
    // on-disk bytes). Populated by the site-side SiteAuditBacklogReporter
    // hosted service every 30 s. Defaults to null so existing producers /
    // tests that don't refresh the snapshot stay valid; the central health
    // surface treats null as "no data yet" rather than a zeroed queue.
    SiteAuditBacklogSnapshot? SiteAuditBacklog = null);

/// <summary>
/// Broadcast wrapper used between central nodes to keep per-node
/// CentralHealthAggregator state in sync. ClusterClient load-balances each
/// incoming SiteHealthReport to one central node; that node re-publishes
/// this wrapper on a DistributedPubSub topic so the peer node's aggregator
/// also processes the report (idempotently — sequence numbers guard against
/// double-counting).
/// </summary>
public record SiteHealthReportReplica(SiteHealthReport Report);
