using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace ZB.MOM.WW.LmxProxy.Client.Tests;

public class ServiceCollectionExtensionsTests
{
    [Fact]
    public void AddLmxProxyClient_WithConfiguration_RegistersSingleton()
    {
        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?>
            {
                ["LmxProxy:Host"] = "localhost",
                ["LmxProxy:Port"] = "50051",
            })
            .Build();

        var services = new ServiceCollection();
        services.AddLmxProxyClient(config);

        using var provider = services.BuildServiceProvider();
        var client = provider.GetRequiredService<ILmxProxyClient>();
        Assert.NotNull(client);
        Assert.IsType<LmxProxyClient>(client);
    }

    [Fact]
    public void AddLmxProxyClient_WithBuilderAction_RegistersSingleton()
    {
        var services = new ServiceCollection();
        services.AddLmxProxyClient(b => b.WithHost("localhost").WithPort(50051));

        using var provider = services.BuildServiceProvider();
        var client = provider.GetRequiredService<ILmxProxyClient>();
        Assert.NotNull(client);
    }

    [Fact]
    public void AddLmxProxyClient_WithNamedSection_RegistersSingleton()
    {
        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?>
            {
                ["CustomProxy:Host"] = "10.0.0.1",
                ["CustomProxy:Port"] = "50052",
            })
            .Build();

        var services = new ServiceCollection();
        services.AddLmxProxyClient(config, "CustomProxy");

        using var provider = services.BuildServiceProvider();
        var client = provider.GetRequiredService<ILmxProxyClient>();
        Assert.NotNull(client);
    }

    [Fact]
    public void AddScopedLmxProxyClient_RegistersScoped()
    {
        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?>
            {
                ["LmxProxy:Host"] = "localhost",
            })
            .Build();

        var services = new ServiceCollection();
        services.AddScopedLmxProxyClient(config);

        using var provider = services.BuildServiceProvider();
        using var scope = provider.CreateScope();
        var client = scope.ServiceProvider.GetRequiredService<ILmxProxyClient>();
        Assert.NotNull(client);
    }

    [Fact]
    public void AddNamedLmxProxyClient_RegistersKeyedSingleton()
    {
        var services = new ServiceCollection();
        services.AddNamedLmxProxyClient("primary", b => b.WithHost("host-a").WithPort(50051));
        services.AddNamedLmxProxyClient("secondary", b => b.WithHost("host-b").WithPort(50052));

        using var provider = services.BuildServiceProvider();
        var primary = provider.GetRequiredKeyedService<ILmxProxyClient>("primary");
        var secondary = provider.GetRequiredKeyedService<ILmxProxyClient>("secondary");
        Assert.NotNull(primary);
        Assert.NotNull(secondary);
        Assert.NotSame(primary, secondary);
    }
}
