using Akka.Cluster;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using ScadaLink.Host.Actors;

namespace ScadaLink.Host.Health;

/// <summary>
/// Health check that returns healthy only if this node is the active (leader) node
/// in the Akka.NET cluster. Used by Traefik to route traffic to the active node.
/// </summary>
public class ActiveNodeHealthCheck : IHealthCheck
{
    private readonly AkkaHostedService _akkaService;

    public ActiveNodeHealthCheck(AkkaHostedService akkaService)
    {
        _akkaService = akkaService;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        var system = _akkaService.ActorSystem;
        if (system == null)
            return Task.FromResult(HealthCheckResult.Unhealthy("ActorSystem not yet available."));

        var cluster = Cluster.Get(system);
        var self = cluster.SelfMember;

        if (self.Status != MemberStatus.Up)
            return Task.FromResult(HealthCheckResult.Unhealthy($"Node not Up (status: {self.Status})."));

        var leader = cluster.State.Leader;
        if (leader != null && leader == self.Address)
            return Task.FromResult(HealthCheckResult.Healthy("Active node (cluster leader)."));

        return Task.FromResult(HealthCheckResult.Unhealthy("Standby node (not cluster leader)."));
    }
}
