using System.Text;
using NucleicBroker;

// nucleic-brokerd (docs/WINDOWS_PORT.md §2.3): child of nucleic-hostd, NDJSON JSON-RPC 2.0
// over stdio. Exits when stdin closes (hostd died or shut down); on Windows the Job Object
// hostd assigns kills us anyway — this is the graceful path.
//
// stdout carries ONLY protocol lines (the OutboundWriter is its single writer); every
// diagnostic goes to stderr, which hostd logs.

Console.OutputEncoding = Encoding.UTF8;

IWslc wslc =
#if USE_WSLC
    // Create(), not `new`: it configures COM security first, and that MUST precede the process's
    // first COM call (docs/WINDOWS_PORT.md §13.2). Constructing the facade directly compiles fine
    // and silently loses session recovery to a 0x80070542 that reads as "not found".
    NucleicBroker.Wslc.WslcFacade.Create();
#else
    new UnavailableWslc();
#endif
IAiProvider ai = new UnavailableAiProvider();

var stdout = new StreamWriter(Console.OpenStandardOutput(), new UTF8Encoding(false)) { AutoFlush = false };
var outbound = new OutboundWriter(stdout);
var service = new BrokerService(wslc, ai, outbound);

using var stdin = new StreamReader(Console.OpenStandardInput(), Encoding.UTF8);
var inFlight = new List<Task>();
for (string? line; (line = await stdin.ReadLineAsync()) is not null;)
{
    if (line.Length == 0) continue;
    // Requests run concurrently (a long image.pull must not block container.list); the
    // outbound writer serializes their responses. Track them so shutdown can drain.
    inFlight.Add(service.HandleLineAsync(line));
    inFlight.RemoveAll(t => t.IsCompleted);
}

await Task.WhenAll(inFlight).ConfigureAwait(false);
await outbound.CompleteAsync().ConfigureAwait(false);
