using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using ZB.MOM.WW.MxGateway.Server;
using ZB.MOM.WW.MxGateway.Server.Dashboard;
using ZB.MOM.WW.MxGateway.Server.Dashboard.Hubs;

namespace ZB.MOM.WW.MxGateway.Tests.Gateway.Dashboard;

public sealed class DashboardHubsRegistrationTests
{
    /// <summary>Verifies that dashboard build maps all three hubs and token endpoint.</summary>
    [Fact]
    public async Task Build_WhenDashboardEnabled_MapsAllThreeHubsAndTokenEndpoint()
    {
        await using WebApplication app = GatewayApplication.Build([]);
        IReadOnlyList<RouteEndpoint> endpoints = ((IEndpointRouteBuilder)app).DataSources
            .SelectMany(source => source.Endpoints)
            .OfType<RouteEndpoint>()
            .ToList();

        Assert.Contains(endpoints, endpoint => endpoint.RoutePattern.RawText == "/hubs/snapshot/negotiate");
        Assert.Contains(endpoints, endpoint => endpoint.RoutePattern.RawText == "/hubs/alarms/negotiate");
        Assert.Contains(endpoints, endpoint => endpoint.RoutePattern.RawText == "/hubs/events/negotiate");
        Assert.Contains(endpoints, endpoint =>
            endpoint.Metadata.GetMetadata<IEndpointNameMetadata>()?.EndpointName == "DashboardHubToken");
    }

    /// <summary>Verifies that dashboard build registers hub token service and connection factory.</summary>
    [Fact]
    public async Task Build_WhenDashboardEnabled_RegistersHubTokenServiceAndConnectionFactory()
    {
        await using WebApplication app = GatewayApplication.Build([]);

        // HubTokenService is singleton; DashboardHubConnectionFactory is scoped
        // (it captures NavigationManager and AuthenticationStateProvider which
        // are themselves per-circuit).
        HubTokenService tokens = app.Services.GetRequiredService<HubTokenService>();
        Assert.NotNull(tokens);

        using IServiceScope scope = app.Services.CreateScope();
        DashboardHubConnectionFactory factory = scope.ServiceProvider
            .GetRequiredService<DashboardHubConnectionFactory>();
        Assert.NotNull(factory);
    }
}
