using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ZB.MOM.WW.OtOpcUa.AdminUI.Hubs;
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns;
using ZB.MOM.WW.OtOpcUa.Commons.Browsing;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser;
namespace ZB.MOM.WW.OtOpcUa.AdminUI;
public static class EndpointRouteBuilderExtensions
{
///
/// Mounts the AdminUI Razor components and the AdminUI static asset pipeline at the root.
/// Call from the fused Host's Program.cs alongside app.MapOtOpcUaAuth().
///
/// The root component type for Razor pages.
/// The endpoint route builder.
/// The same endpoint route builder, for chaining.
public static IEndpointRouteBuilder MapAdminUI(this IEndpointRouteBuilder app)
where TApp : IComponent
{
// Razor class library static assets (_content/ZB.MOM.WW.OtOpcUa.AdminUI/**) are
// served via the Host's app.UseStaticFiles() middleware which must run BEFORE
// UseAuthentication() — see Program.cs.
app.MapRazorComponents()
.AddInteractiveServerRenderMode();
return app;
}
///
/// Adds AdminUI services to the dependency injection container.
///
/// The service collection.
/// The same service collection, for chaining.
public static IServiceCollection AddAdminUI(this IServiceCollection services)
{
services.AddRazorComponents().AddInteractiveServerComponents();
services.AddOtOpcUaDriverStatusServices();
// Browse pipeline — see docs/plans/2026-05-28-driver-browsers-design.md
services.AddSingleton();
services.AddHostedService();
services.AddScoped();
services.AddScoped();
services.AddSingleton();
services.AddSingleton();
// Universal Discover-backed fallback browser (Wave 0). IDriverFactory is bound by the
// fused Host's DriverFactoryBootstrap; a standalone AdminUI has none → NullDriverFactory
// → CanBrowse false → pickers gracefully stay manual-entry (design §6).
services.AddSingleton(sp => new DiscoveryDriverBrowser(
sp.GetService() ?? NullDriverFactory.Instance,
sp.GetRequiredService>()));
// Roslyn-backed Monaco script-editor analysis (diagnostics/completions/hover/...).
services.AddScoped();
services.AddScoped();
// Certificate-store actions (trust/untrust/delete) for the /certificates page.
services.AddSingleton();
// Structured audit-event sink: forwards AuditEvents to the ControlPlane AuditWriter singleton.
services.AddSingleton();
return services;
}
}