using Application.Abstractions.Messaging;
using Application.Messaging;
using Microsoft.Extensions.DependencyInjection;

namespace Application;

public static class DependencyInjection
{
    private static readonly Type[] HandlerInterfaces =
    [
        typeof(ICommandHandler<>),
        typeof(ICommandHandler<,>),
        typeof(IQueryHandler<,>)
    ];

    public static IServiceCollection AddApplication(this IServiceCollection services)
    {
        var assembly = typeof(DependencyInjection).Assembly;

        foreach (var implementationType in assembly.GetTypes())
        {
            if (implementationType.IsAbstract || implementationType.IsInterface || implementationType.IsGenericTypeDefinition)
            {
                continue;
            }

            foreach (var serviceType in implementationType.GetInterfaces())
            {
                if (serviceType.IsGenericType && HandlerInterfaces.Contains(serviceType.GetGenericTypeDefinition()))
                {
                    services.AddScoped(serviceType, implementationType);
                }
            }
        }

        services.AddScoped<Sender>();
        services.AddScoped<ISender>(sp => sp.GetRequiredService<Sender>());
        services.AddScoped<IMediator>(sp => sp.GetRequiredService<Sender>());

        return services;
    }
}