using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace ScadaLink.ClusterInfrastructure.Tests;

/// <summary>
/// CI-002: Tests that the DI extension methods do real work rather than
/// silently returning success. <see cref="ServiceCollectionExtensions.AddClusterInfrastructure"/>
/// must register the <see cref="ClusterOptionsValidator"/> so misconfiguration
/// fails fast, and the unimplemented actor-registration placeholder must fail
/// loudly rather than masquerade as a completed registration.
/// </summary>
public class ServiceCollectionExtensionsTests
{
    [Fact]
    public void AddClusterInfrastructure_RegistersOptionsValidator()
    {
        var services = new ServiceCollection();

        services.AddClusterInfrastructure();

        var validators = services
            .Where(d => d.ServiceType == typeof(IValidateOptions<ClusterOptions>))
            .ToList();
        Assert.NotEmpty(validators);

        using var provider = services.BuildServiceProvider();
        var validator = provider.GetService<IValidateOptions<ClusterOptions>>();
        Assert.IsType<ClusterOptionsValidator>(validator);
    }

    [Fact]
    public void AddClusterInfrastructure_ValidatorRejectsBadOptionsAtResolution()
    {
        var services = new ServiceCollection();
        services.AddClusterInfrastructure();
        // A MinNrOfMembers of 2 blocks the cluster singleton after failover.
        services.Configure<ClusterOptions>(o =>
        {
            o.SeedNodes = new List<string> { "akka.tcp://scadalink@node1:8081" };
            o.MinNrOfMembers = 2;
        });

        using var provider = services.BuildServiceProvider();

        var ex = Assert.Throws<OptionsValidationException>(
            () => provider.GetRequiredService<IOptions<ClusterOptions>>().Value);
        Assert.Contains("MinNrOfMembers", ex.Message);
    }

    [Fact]
    public void AddClusterInfrastructureActors_ThrowsRatherThanSilentlySucceeding()
    {
        var services = new ServiceCollection();

        Assert.Throws<NotImplementedException>(() => services.AddClusterInfrastructureActors());
    }
}
