using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace DigitalData.Core.API
{
    /// <summary>
    /// Provides a convention to remove controllers from the application based on specified conditions.
    /// </summary>
    public class RemoveIfControllerConvention : IApplicationModelConvention
    {
        /// <summary>
        /// A list of conditions that determine if a controller should be removed.
        /// </summary>
        private readonly List<Func<ControllerModel, bool>> _andIfConditions = new();

        /// <summary>
        /// Applies the convention to the application, removing controllers that meet all specified conditions.
        /// </summary>
        /// <param name="application">The application model representing the MVC application.</param>
        public void Apply(ApplicationModel application)
        {
            List<ControllerModel> controllersToRemove = new();

            // Iterate over all controllers in the application.
            foreach (var controller in application.Controllers)
            {
                // If all conditions are met for this controller, mark it for removal.
                if (_andIfConditions.All(condition => condition(controller)))
                    controllersToRemove.Add(controller);
            }

            // Remove the controllers that met all conditions.
            foreach (var controllerToRemove in controllersToRemove)
                application.Controllers.Remove(controllerToRemove);
        }

        /// <summary>
        /// Adds a new condition to the list of conditions that a controller must meet to be removed.
        /// </summary>
        /// <param name="condition">The condition that determines if a controller should be removed.</param>
        /// <returns>The current instance of <see cref="RemoveIfControllerConvention"/> to allow for method chaining.</returns>
        public RemoveIfControllerConvention AndIf(Func<ControllerModel, bool> condition)
        {
            _andIfConditions.Add(condition);
            return this;
        }
    }
}