using Mbproxy;
using Mbproxy.Proxy;
using Microsoft.Extensions.Hosting.Systemd;
using Microsoft.Extensions.Hosting.WindowsServices;

var builder = Host.CreateApplicationBuilder(args);

// Init-system integration. Both helpers self-detect their host and are no-ops
// otherwise, so calling both unconditionally is correct on every platform:
//   - AddWindowsService(): active only when launched by the Windows SCM.
//   - AddSystemd():        active only when launched by systemd (wires sd_notify
//                          readiness; SIGTERM shutdown is handled by the host).
builder.Services.AddWindowsService();
builder.Services.AddSystemd();

// Wire up structured config, Serilog, and typed options. AddMbproxySerilog selects
// the platform diagnostic sink (Windows Event Log / syslog / none) internally.
builder.AddMbproxySerilog();
builder.AddMbproxyOptions();

// PDU pipeline: BcdPduPipeline is stateless (per-call correlation flows through
// PerPlcContext.CurrentRequest set by the multiplexer); registering as singleton is fine
// and avoids repeated construction.
builder.Services.AddSingleton<IPduPipeline, BcdPduPipeline>();

// Proxy worker — owns all PlcListeners, logs mbproxy.startup.ready, and drives the admin
// endpoint's lifecycle. Registered as singleton so StatusSnapshotBuilder can inject
// ProxyWorker directly and access its Supervisors dictionary.
builder.Services.AddSingleton<ProxyWorker>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<ProxyWorker>());

// Admin endpoint (Kestrel read-only status page). Not registered as IHostedService —
// ProxyWorker drives its lifecycle so admin starts after listeners and stops AFTER the
// in-flight drain.
builder.AddMbproxyAdmin();

await builder.Build().RunAsync();
