using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using OpenHarbor.CQRS.Abstractions.Discovery;
using OpenHarbor.CQRS.AspNetCore.Abstractions.Attributes;

namespace OpenHarbor.CQRS.AspNetCore.Mvc;

public class CommandControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
    private readonly ServiceProvider _serviceProvider;

    public CommandControllerFeatureProvider(ServiceProvider serviceProvider)
    {
        this._serviceProvider = serviceProvider;
    }

    public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
    {
        var commandDiscovery = this._serviceProvider.GetRequiredService<ICommandDiscovery>();
        foreach (var f in commandDiscovery.GetCommands())
        {
            var ignoreAttribute = f.CommandType.GetCustomAttribute<CommandControllerIgnoreAttribute>();
            if (ignoreAttribute != null)
                continue;

            if (f.CommandResultType == null)
            {
                var controllerType = typeof(CommandController<>).MakeGenericType(f.CommandType);
                var controllerTypeInfo = controllerType.GetTypeInfo();
                feature.Controllers.Add(controllerTypeInfo);
            }
            else
            {
                var controllerType = typeof(CommandController<,>).MakeGenericType(f.CommandType, f.CommandResultType);
                var controllerTypeInfo = controllerType.GetTypeInfo();
                feature.Controllers.Add(controllerTypeInfo);
            }
        }
    }
}