using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ZB.MOM.WW.MxGateway.Contracts.Proto;
using ZB.MOM.WW.MxGateway.Worker.Sta;
namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;
///
/// Manages the runtime session between the worker and the MXAccess COM instance on an STA thread.
///
public interface IWorkerRuntimeSession : IDisposable
{
///
/// Starts the session, creates the MXAccess COM object, and returns ready metadata.
///
/// Identifier of the session.
/// ID of the worker process.
/// Token to cancel the asynchronous operation.
/// Asynchronous task returning worker readiness metadata.
Task StartAsync(
string sessionId,
int workerProcessId,
CancellationToken cancellationToken = default);
///
/// Dispatches an STA command to the MXAccess runtime and returns the reply.
///
/// STA command to execute on the STA thread.
/// Asynchronous task returning the command reply.
Task DispatchAsync(StaCommand command);
///
/// Captures a heartbeat snapshot of the runtime state.
///
/// The current heartbeat snapshot.
WorkerRuntimeHeartbeatSnapshot CaptureHeartbeat();
///
/// Drains up to the specified number of pending events from the queue.
///
/// Maximum number of events to drain.
/// List of drained events.
IReadOnlyList DrainEvents(uint maxEvents);
///
/// Drains pending events bounded by both a count cap and a byte budget, so a caller building a
/// single reply frame never removes an event it cannot ship.
///
///
/// Declared as a second method rather than a default interface method: the worker targets
/// .NET Framework 4.8, which has no runtime support for default interface members.
///
/// Maximum number of events to drain; 0 means "no count limit".
/// Byte budget for the drained events' estimated serialized size.
/// The drained events and the truncation facts describing what stayed queued.
WorkerEventDrainResult DrainEvents(uint maxEvents, int maxTotalBytes);
///
/// Waits until the outbound event queue has something for the caller to look at (an
/// enqueued event or a recorded fault), the fallback timeout elapses, or the token is
/// cancelled. Lets a drain loop be signal-driven instead of polling.
///
///
/// Declared on the interface because the pipe session only ever sees an
/// , never the queue behind it; .NET Framework 4.8 has
/// no default interface members, so every implementation supplies it. The wait's outcome is
/// not surfaced: the caller re-drains and re-checks after every
/// wait, because the signal is coalesced and the timeout is a ceiling, not a poll period.
///
/// Precondition: at most one waiter. The implementation's wake signal carries a
/// single permit, which is sufficient only because a session has exactly one event
/// drain loop; a second concurrent waiter would degrade to the fallback timeout.
///
///
/// Maximum time to wait before the wait completes unsignalled.
/// Token cancelling the wait.
/// A task that completes when the queue is signalled or the timeout elapses.
Task WaitForEventsAsync(TimeSpan timeout, CancellationToken cancellationToken);
///
/// Drains a pending fault from the queue, if any.
///
/// The pending fault, or if none is queued.
WorkerFault? DrainFault();
///
/// Cancels a pending command by correlation ID.
///
/// Correlation ID of the command to cancel.
/// True if the command was found and cancelled; otherwise, false.
bool CancelCommand(string correlationId);
///
/// Requests a graceful shutdown of the session.
///
void RequestShutdown();
///
/// Shuts down the session gracefully within the specified timeout.
///
/// Maximum time to allow for graceful shutdown.
/// Token to cancel the asynchronous operation.
/// Asynchronous task returning the shutdown result.
Task ShutdownGracefullyAsync(
TimeSpan timeout,
CancellationToken cancellationToken = default);
}