using System.Diagnostics;
using AVSCartonShipmentVerifier.Configuration;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
namespace AVSCartonShipmentVerifier.Hosting;
///
/// Opens the default browser once the web server has started (Windows desktop-style launch).
///
internal sealed class LaunchBrowserHostedService : IHostedService
{
private readonly IHostApplicationLifetime _lifetime;
private readonly IOptions _options;
private readonly IServer _server;
private readonly ILogger _logger;
public LaunchBrowserHostedService(
IServer server,
IHostApplicationLifetime lifetime,
IOptions options,
ILogger logger)
{
_server = server;
_lifetime = lifetime;
_options = options;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var opts = _options.Value;
if (!opts.LaunchBrowser)
return Task.CompletedTask;
_lifetime.ApplicationStarted.Register(OpenBrowser);
return Task.CompletedTask;
}
private void OpenBrowser()
{
try
{
var url = ResolveUrl();
if (string.IsNullOrWhiteSpace(url))
{
_logger.LogWarning("Could not determine URL to open in the browser.");
return;
}
if (OperatingSystem.IsWindows())
{
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
}
else if (OperatingSystem.IsMacOS())
{
Process.Start("open", url);
}
else
{
Process.Start(new ProcessStartInfo("xdg-open", url) { UseShellExecute = true });
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to launch the default browser.");
}
}
private string? ResolveUrl()
{
var configured = _options.Value.BrowserUrl;
if (!string.IsNullOrWhiteSpace(configured))
return configured;
var addresses = _server.Features.Get()?.Addresses;
if (addresses is null || addresses.Count == 0)
return null;
return addresses.FirstOrDefault(static a => a.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
?? addresses.FirstOrDefault(static a => a.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
?? addresses.FirstOrDefault();
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}