using LmxFakeProxy; using LmxFakeProxy.Bridge; using LmxFakeProxy.Services; using LmxFakeProxy.Sessions; var builder = WebApplication.CreateBuilder(args); // Configuration: env vars take precedence over CLI args var port = Environment.GetEnvironmentVariable("PORT") ?? GetArg(args, "--port") ?? "50051"; var opcEndpoint = Environment.GetEnvironmentVariable("OPC_ENDPOINT") ?? GetArg(args, "--opc-endpoint") ?? "opc.tcp://localhost:50000"; var opcPrefix = Environment.GetEnvironmentVariable("OPC_PREFIX") ?? GetArg(args, "--opc-prefix") ?? "ns=3;s="; var apiKey = Environment.GetEnvironmentVariable("API_KEY") ?? GetArg(args, "--api-key"); builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(int.Parse(port), listenOptions => { listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2; }); }); // Register services builder.Services.AddSingleton(new SessionManager(apiKey)); builder.Services.AddSingleton(new TagMapper(opcPrefix)); builder.Services.AddSingleton(sp => new OpcUaBridge(opcEndpoint, sp.GetRequiredService>())); builder.Services.AddGrpc(); var app = builder.Build(); app.MapGrpcService(); app.MapGet("/", () => "LmxFakeProxy is running"); // Connect to OPC UA backend var logger = app.Services.GetRequiredService>(); logger.LogInformation("LmxFakeProxy starting on port {Port}", port); logger.LogInformation("OPC UA endpoint: {Endpoint}, prefix: {Prefix}", opcEndpoint, opcPrefix); logger.LogInformation("API key enforcement: {Enforced}", apiKey != null ? "enabled" : "disabled (accept all)"); var bridge = app.Services.GetRequiredService(); try { await ((OpcUaBridge)bridge).ConnectAsync(); logger.LogInformation("OPC UA bridge connected"); } catch (Exception ex) { logger.LogWarning(ex, "Initial OPC UA connection failed — will retry when first request arrives"); } await app.RunAsync(); static string? GetArg(string[] args, string name) { var idx = Array.IndexOf(args, name); return idx >= 0 && idx + 1 < args.Length ? args[idx + 1] : null; }