using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ZB.MOM.WW.Health;
using ZB.MOM.WW.Health.Akka;
using ZB.MOM.WW.Health.EntityFrameworkCore;
using ZB.MOM.WW.OtOpcUa.Configuration;

namespace ZB.MOM.WW.OtOpcUa.Host.Health;

public static class HealthEndpoints
{
    /// <summary>
    /// Registers the shared ZB.MOM.WW health probes. Tier semantics preserved: configdb + akka on
    /// ready+active; admin-leader on active only.
    /// </summary>
    /// <param name="services">The service collection to register the health checks on.</param>
    /// <returns>The same service collection, for chaining.</returns>
    public static IServiceCollection AddOtOpcUaHealth(this IServiceCollection services)
    {
        services.AddHealthChecks()
            .AddTypeActivatedCheck<DatabaseHealthCheck<OtOpcUaConfigDbContext>>(
                "configdb",
                failureStatus: null,
                tags: new[] { ZbHealthTags.Ready, ZbHealthTags.Active },
                args: new DatabaseHealthCheckOptions<OtOpcUaConfigDbContext>
                {
                    ProbeQuery = static (db, ct) => db.Deployments.AsNoTracking().Take(1).ToListAsync(ct),
                })
            .AddTypeActivatedCheck<AkkaClusterHealthCheck>(
                "akka",
                failureStatus: null,
                tags: new[] { ZbHealthTags.Ready, ZbHealthTags.Active },
                args: AkkaClusterStatusPolicy.OtOpcUaCompat)
            .AddTypeActivatedCheck<ActiveNodeHealthCheck>(
                "admin-leader",
                failureStatus: null,
                tags: new[] { ZbHealthTags.Active },
                args: "admin");
        return services;
    }

    /// <summary>Maps the OtOpcUa health check endpoints to the route builder.</summary>
    /// <param name="app">The endpoint route builder.</param>
    /// <returns>The same endpoint route builder, for chaining.</returns>
    public static IEndpointRouteBuilder MapOtOpcUaHealth(this IEndpointRouteBuilder app)
    {
        app.MapZbHealth();
        return app;
    }
}
