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

namespace ZB.MOM.WW.LmxProxy.Client;

/// <summary>
/// Extension methods for registering LmxProxy client services in the DI container.
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>Registers a singleton ILmxProxyClient from the "LmxProxy" config section.</summary>
    public static IServiceCollection AddLmxProxyClient(
        this IServiceCollection services, IConfiguration configuration)
    {
        return services.AddLmxProxyClient(configuration, "LmxProxy");
    }

    /// <summary>Registers a singleton ILmxProxyClient from a named config section.</summary>
    public static IServiceCollection AddLmxProxyClient(
        this IServiceCollection services, IConfiguration configuration, string sectionName)
    {
        services.AddSingleton<ILmxProxyClientFactory>(
            sp => new LmxProxyClientFactory(configuration));
        services.AddSingleton<ILmxProxyClient>(sp =>
        {
            var factory = sp.GetRequiredService<ILmxProxyClientFactory>();
            return factory.CreateClient(sectionName);
        });
        return services;
    }

    /// <summary>Registers a singleton ILmxProxyClient via builder action.</summary>
    public static IServiceCollection AddLmxProxyClient(
        this IServiceCollection services, Action<LmxProxyClientBuilder> configure)
    {
        services.AddSingleton<ILmxProxyClient>(sp =>
        {
            var builder = new LmxProxyClientBuilder();
            configure(builder);
            return builder.Build();
        });
        return services;
    }

    /// <summary>Registers a scoped ILmxProxyClient from the "LmxProxy" config section.</summary>
    public static IServiceCollection AddScopedLmxProxyClient(
        this IServiceCollection services, IConfiguration configuration)
    {
        services.AddSingleton<ILmxProxyClientFactory>(
            sp => new LmxProxyClientFactory(configuration));
        services.AddScoped<ILmxProxyClient>(sp =>
        {
            var factory = sp.GetRequiredService<ILmxProxyClientFactory>();
            return factory.CreateClient();
        });
        return services;
    }

    /// <summary>Registers a keyed singleton ILmxProxyClient.</summary>
    public static IServiceCollection AddNamedLmxProxyClient(
        this IServiceCollection services, string name, Action<LmxProxyClientBuilder> configure)
    {
        services.AddKeyedSingleton<ILmxProxyClient>(name, (sp, key) =>
        {
            var builder = new LmxProxyClientBuilder();
            configure(builder);
            return builder.Build();
        });
        return services;
    }
}
