namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;

/// <summary>
///     Sink for driver-health state-change notifications. The runtime DI wires the
///     Akka-DistributedPubSub-backed implementation; tests and dev-stub paths use
///     <see cref="NullDriverHealthPublisher"/> to opt out without changing call sites.
/// </summary>
public interface IDriverHealthPublisher
{
    /// <summary>
    ///     Publishes a health snapshot for one driver instance. Implementations must be
    ///     non-blocking and tolerant of being called from any thread.
    /// </summary>
    /// <param name="clusterId">The cluster the driver instance belongs to.</param>
    /// <param name="driverInstanceId">The driver instance the snapshot describes.</param>
    /// <param name="health">The current health snapshot.</param>
    /// <param name="errorCount5Min">The number of errors observed in the trailing 5-minute window.</param>
    /// <param name="rediscoveryNeededUtc">
    ///     When the driver last raised <see cref="IRediscoverable.OnRediscoveryNeeded"/>, or null if never
    ///     (or if it is not an <see cref="IRediscoverable"/>). Advisory: it prompts an operator to
    ///     re-browse, and never rebuilds the served address space.
    /// </param>
    /// <param name="rediscoveryReason">The driver-supplied reason from that event; null when
    ///     <paramref name="rediscoveryNeededUtc"/> is null.</param>
    void Publish(
        string clusterId,
        string driverInstanceId,
        DriverHealth health,
        int errorCount5Min,
        DateTime? rediscoveryNeededUtc = null,
        string? rediscoveryReason = null);
}

/// <summary>
///     Drop-in no-op for tests and dev-stub paths. Production wires the Akka-backed
///     implementation in the Runtime project.
/// </summary>
public sealed class NullDriverHealthPublisher : IDriverHealthPublisher
{
    /// <summary>Singleton instance.</summary>
    public static readonly NullDriverHealthPublisher Instance = new();

    private NullDriverHealthPublisher() { }

    /// <inheritdoc />
    public void Publish(
        string clusterId,
        string driverInstanceId,
        DriverHealth health,
        int errorCount5Min,
        DateTime? rediscoveryNeededUtc = null,
        string? rediscoveryReason = null)
    { /* no-op */ }
}
