using Microsoft.Extensions.Logging.Abstractions;
using ZB.MOM.WW.MxGateway.Server.Configuration;
using ZB.MOM.WW.MxGateway.Server.Dashboard.Hubs;
using ZB.MOM.WW.MxGateway.Server.Grpc;
using ZB.MOM.WW.MxGateway.Server.Metrics;
namespace ZB.MOM.WW.MxGateway.Server.Sessions;
///
/// Dependencies a needs to construct and own its
/// . Bundled so the session constructor stays a
/// single optional parameter rather than four, and so unit tests that build a session
/// directly get a working distributor from without wiring DI.
///
///
/// Maps worker IPC WorkerEvent frames to public MxEvents. The distributor
/// pump applies this once per event in worker order, mirroring the mapping
/// EventStreamService.ProduceEventsAsync used previously.
///
///
/// Supplies the distributor's per-subscriber queue capacity and replay ring-buffer
/// bounds (,
/// ,
/// ).
///
/// Logger for the distributor pump lifecycle.
/// Clock used to timestamp and age-evict replay entries.
///
/// Gateway metrics sink used by the session's per-subscriber overflow handler to record
/// the queue-overflow counter and, for legacy single-subscriber FailFast, the session
/// fault. Carrying it here keeps the distributor decoupled from the metrics type while
/// preserving the observability the pre-epic per-RPC overflow path emitted.
///
///
/// Sink the session's internal dashboard mirror loop publishes raw session
/// MxEvents to. When non-null the session registers an internal distributor
/// subscriber on becoming Ready and mirrors every fanned event to the dashboard
/// EventsHub group regardless of whether a gRPC client is streaming. When null
/// (unit tests that don't exercise the dashboard mirror) no mirror is started.
///
///
/// The session's effective multi-subscriber mode. Carried here so the session
/// can pass it to its at construction — the
/// distributor is created at MarkReady (for the dashboard mirror) before any gRPC
/// subscriber attaches, so the mode cannot be learned from a later
/// AttachEventSubscriber call. The distributor gates its FailFast session-fault
/// decision on this mode (single-subscriber only) instead of a live count snapshot,
/// closing the false-FailFast race. Defaults to
/// (single-subscriber) so existing call sites and unit tests are unchanged.
///
public sealed record SessionEventStreaming(
MxAccessGrpcMapper Mapper,
EventOptions EventOptions,
ILogger DistributorLogger,
TimeProvider TimeProvider,
GatewayMetrics Metrics,
IDashboardEventBroadcaster? DashboardBroadcaster = null,
bool AllowMultipleEventSubscribers = false)
{
///
/// Defaults used when a session is constructed without explicit streaming
/// dependencies (unit tests). Uses a fresh mapper, default event options, a no-op
/// logger, the system clock, a fresh metrics sink, and no dashboard mirror.
///
public static SessionEventStreaming Default { get; } = new(
new MxAccessGrpcMapper(),
new EventOptions(),
NullLogger.Instance,
TimeProvider.System,
new GatewayMetrics());
}