namespace DigitalData.Core.API;

/// <summary>
/// Provides extension methods for adding middleware to the application's request pipeline.
/// </summary>
public static class DIExtensions
{
    /// <summary>
    /// Adds the <see cref="CSPMiddleware"/> to the application's request pipeline to include 
    /// Content Security Policy (CSP) headers in the HTTP response.
    /// </summary>
    /// <param name="app">The application builder.</param>
    /// <param name="policy">
    /// The CSP policy string with placeholders. The first format parameter {0} will be replaced 
    /// by the nonce value.
    /// </param>
    /// <returns>The application builder with the CSP middleware added.</returns>
    public static IApplicationBuilder UseCSPMiddleware(this IApplicationBuilder app, string policy)
        => app.UseMiddleware<CSPMiddleware>(policy);

    /// <summary>
    /// Checks if the DiP (Development in Production) mode is enabled for the WebApplicationBuilder.
    /// </summary>
    /// <param name="builder">The WebApplicationBuilder instance.</param>
    /// <returns>True if DiP mode is enabled; otherwise, false.</returns>
    public static bool IsDiP(this WebApplicationBuilder builder) => builder.Configuration.GetValue<bool>("DiPMode");

    /// <summary>
    /// Checks if the DiP (Development in Production) mode is enabled for the WebApplication.
    /// </summary>
    /// <param name="app">The WebApplication instance.</param>
    /// <returns>True if DiP mode is enabled; otherwise, false.</returns>
    public static bool IsDiP(this WebApplication app) => app.Configuration.GetValue<bool>("DiPMode");

    /// <summary>
    /// Checks if the environment is Development or DiP (Development in Production) mode is enabled for the WebApplicationBuilder.
    /// </summary>
    /// <param name="builder">The WebApplicationBuilder instance.</param>
    /// <returns>True if the environment is Development or DiP mode is enabled; otherwise, false.</returns>
    public static bool IsDevOrDiP(this WebApplicationBuilder builder) => builder.Environment.IsDevelopment() || builder.IsDiP();

    /// <summary>
    /// Checks if the environment is Development or DiP (Development in Production) mode is enabled for the WebApplication.
    /// </summary>
    /// <param name="app">The WebApplication instance.</param>
    /// <returns>True if the environment is Development or DiP mode is enabled; otherwise, false.</returns>
    public static bool IsDevOrDiP(this WebApplication app) => app.Environment.IsDevelopment() || app.IsDiP();

		/// <summary>
		/// Configures the services with options from the specified section of the appsettings.json file.
		/// </summary>
		/// <typeparam name="T">The options class type. Must be a reference type.</typeparam>
		/// <param name="builder">The WebApplicationBuilder instance.</param>
		/// <returns>The WebApplicationBuilder instance for chaining.</returns>
		/// <exception cref="InvalidOperationException">Thrown if the section is not found in the configuration.</exception>
		public static WebApplicationBuilder ConfigureBySection<T>(this WebApplicationBuilder builder) where T : class
		{
			var section = builder.Configuration.GetSection(typeof(T).Name);
			if (!section.Exists())
				throw new InvalidOperationException($"Section '{typeof(T).Name}' not found in appsettings.");

			builder.Services.Configure<T>(section);
			return builder;
		}
	}