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

namespace ZB.MOM.WW.ScadaBridge.DeploymentManager;

/// <summary>
/// Payload describing a single deployment-record status change. Kept small —
/// just the deployment identity, the owning instance, and the new status — so
/// it is cheap to raise on the hot path and cheap for subscribers to handle.
/// </summary>
/// <param name="DeploymentId">The unique deployment ID whose status changed.</param>
/// <param name="InstanceId">The instance the deployment record belongs to.</param>
/// <param name="Status">The status the deployment record was just written with.</param>
public readonly record struct DeploymentStatusChange(
    string DeploymentId,
    int InstanceId,
    DeploymentStatus Status);

/// <summary>
/// Push-based deployment-status change notification.
///
/// The design (Component-CentralUI "Real-Time Updates") requires deployment
/// status transitions to push to the UI immediately via SignalR, with no
/// polling. <see cref="DeploymentService"/> raises <see cref="StatusChanged"/>
/// whenever it writes a <see cref="Commons.Entities.Deployment.DeploymentRecord"/>
/// status; the Central UI's deployment-status page subscribes to it and
/// re-renders over its existing Blazor Server SignalR circuit.
///
/// Registered as a DI singleton (see <see cref="ServiceCollectionExtensions.AddDeploymentManager"/>)
/// so the scoped <see cref="DeploymentService"/> and the Blazor circuit's
/// scoped page component share the same instance — both run in the same
/// central Host process.
/// </summary>
public interface IDeploymentStatusNotifier
{
    /// <summary>
    /// Raised after a deployment record's status has been written. Handlers run
    /// synchronously on the caller's thread; subscribers must not block and
    /// should marshal any UI work onto their own dispatcher.
    /// </summary>
    event Action<DeploymentStatusChange>? StatusChanged;

    /// <summary>
    /// Raises <see cref="StatusChanged"/>. Called by <see cref="DeploymentService"/>
    /// at every point a deployment record's status is persisted. A throwing
    /// subscriber must not break the deployment pipeline, so handler exceptions
    /// are swallowed by the implementation.
    /// </summary>
    /// <param name="change">The deployment status change to broadcast to subscribers.</param>
    void NotifyStatusChanged(DeploymentStatusChange change);
}
