using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ZB.MOM.WW.MxGateway.Server.Sessions;

/// <summary>Hosted service that cleanly shuts down all gateway sessions on application shutdown.</summary>
public sealed class SessionShutdownHostedService(
    ISessionManager sessionManager,
    ILogger<SessionShutdownHostedService> logger) : IHostedService
{
    /// <summary>No-op startup hook; this service only has work to do on shutdown.</summary>
    /// <param name="cancellationToken">Token that signals startup should be aborted.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    public Task StartAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    /// <summary>Shuts down all gateway sessions as the host stops.</summary>
    /// <remarks>
    ///     The catch below is now effectively unreachable: <see cref="ISessionManager.ShutdownAsync"/>
    ///     no longer aborts on the host's shutdown timeout, it degrades to a kill sweep and logs a
    ///     per-session warning for each session that failed its graceful close. The clause is kept as
    ///     a cheap guard against that contract regressing, not as an expected path — the operator
    ///     signal for a timed-out shutdown is now those per-session warnings.
    /// </remarks>
    /// <param name="cancellationToken">Token that signals the host's shutdown timeout has elapsed.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    public async Task StopAsync(CancellationToken cancellationToken)
    {
        try
        {
            await sessionManager.ShutdownAsync(cancellationToken).ConfigureAwait(false);
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            logger.LogWarning("Gateway session shutdown was canceled by host shutdown timeout.");
        }
    }
}
