using System.Diagnostics.CodeAnalysis;
using ZB.MOM.WW.MxGateway.Contracts.Proto;
namespace ZB.MOM.WW.MxGateway.Server.Sessions;
public interface ISessionManager
{
/// Opens a new gateway session and launches a worker process.
/// Request payload.
/// Client identity string.
/// API key identifier of the caller creating the session.
/// Token to cancel the asynchronous operation.
/// The newly opened session.
Task OpenSessionAsync(
SessionOpenRequest request,
string? clientIdentity,
string? ownerKeyId,
CancellationToken cancellationToken);
///
/// Opens a new gateway session, stamping the owning API key's dashboard event-visibility
/// tags onto it.
///
/// Request payload.
/// Client identity string.
/// API key identifier of the caller creating the session.
///
/// The owner key's ApiKeyConstraints.DashboardTags. Null or empty opens an untagged
/// session. Never sourced from the client's wire request — see
/// docs/plans/2026-07-10-dashboard-session-acl-tst15.md §3.1.
///
/// Token to cancel the asynchronous operation.
/// The newly opened session.
///
/// The default implementation forwards to the tagless overload, so an implementation that
/// does not model tags (unit-test fakes) opens an untagged session. That is the
/// fail-closed direction: untagged sessions are the least dashboard-visible ones.
///
Task OpenSessionAsync(
SessionOpenRequest request,
string? clientIdentity,
string? ownerKeyId,
IReadOnlyList? ownerDashboardTags,
CancellationToken cancellationToken)
=> OpenSessionAsync(request, clientIdentity, ownerKeyId, cancellationToken);
/// Attempts to retrieve a session by ID.
/// Identifier of the session.
/// The retrieved session, if found.
/// True if the session exists; otherwise false.
bool TryGetSession(
string sessionId,
[MaybeNullWhen(false)] out GatewaySession session);
/// Invokes a command on the worker for the specified session.
/// Identifier of the session.
/// Command to invoke.
/// Token to cancel the asynchronous operation.
/// The command reply from the worker.
Task InvokeAsync(
string sessionId,
WorkerCommand command,
CancellationToken cancellationToken);
/// Closes a session and terminates its worker process.
/// Identifier of the session to close.
/// Token to cancel the asynchronous operation.
/// The result of closing the session.
Task CloseSessionAsync(
string sessionId,
CancellationToken cancellationToken);
///
/// Forcefully terminates a session's worker without attempting graceful shutdown,
/// transitions the session to Closed, and removes it from the registry.
///
/// Identifier of the session whose worker to kill.
/// Reason for killing the worker (recorded in logs/audit).
/// Token to cancel the asynchronous operation.
/// The result of closing the session.
Task KillWorkerAsync(
string sessionId,
string reason,
CancellationToken cancellationToken);
/// Closes all sessions with expired leases at the specified time.
/// The current time to evaluate expiration against.
/// Token to cancel the asynchronous operation.
/// The number of sessions closed.
///
/// A close that fails does not abandon the rest of the pass: every session selected by this
/// sweep is attempted, and the first failure is then rethrown so the caller still observes
/// (and logs) that the sweep failed. Which failure surfaces is nondeterministic when several
/// closes fail in the same pass, because the closes run concurrently.
///
Task CloseExpiredLeasesAsync(
DateTimeOffset now,
CancellationToken cancellationToken);
/// Shuts down all sessions and the session manager.
///
/// Token that degrades the drain rather than cancelling it. It is passed only to each
/// session's graceful close; the drain loop and the kill fallback are not bound to it, so
/// cancelling turns the drain into a kill sweep instead of abandoning the untried sessions as
/// leaked workers. The call therefore overruns a cancelled token by a bounded amount —
/// roughly ceil(sessionCount / 4) batches of the worker shutdown timeout in the worst
/// case, where 4 is MaxParallelSessionCloses.
///
/// A task that represents the asynchronous operation.
Task ShutdownAsync(CancellationToken cancellationToken);
}