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

namespace StellaOps.Authority.Plugins.Abstractions;

/// <summary>
/// Provides shared services and metadata to Authority plugin registrars during DI setup.
/// </summary>
public sealed class AuthorityPluginRegistrationContext
{
    /// <summary>
    /// Initialises a new registration context.
    /// </summary>
    /// <param name="services">Service collection used to register plugin services.</param>
    /// <param name="plugin">Plugin context describing the manifest and configuration.</param>
    /// <param name="hostConfiguration">Root host configuration available during registration.</param>
    /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception>
    public AuthorityPluginRegistrationContext(
        IServiceCollection services,
        AuthorityPluginContext plugin,
        IConfiguration hostConfiguration)
    {
        Services = services ?? throw new ArgumentNullException(nameof(services));
        Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin));
        HostConfiguration = hostConfiguration ?? throw new ArgumentNullException(nameof(hostConfiguration));
    }

    /// <summary>
    /// Gets the service collection used to register plugin dependencies.
    /// </summary>
    public IServiceCollection Services { get; }

    /// <summary>
    /// Gets the plugin context containing manifest metadata and configuration.
    /// </summary>
    public AuthorityPluginContext Plugin { get; }

    /// <summary>
    /// Gets the root configuration associated with the Authority host.
    /// </summary>
    public IConfiguration HostConfiguration { get; }
}

/// <summary>
/// Registers Authority plugin services for a specific plugin type.
/// </summary>
public interface IAuthorityPluginRegistrar
{
    /// <summary>
    /// Logical plugin type identifier supported by this registrar (e.g. <c>standard</c>, <c>ldap</c>).
    /// </summary>
    string PluginType { get; }

    /// <summary>
    /// Registers services for the supplied plugin context.
    /// </summary>
    /// <param name="context">Registration context containing services and metadata.</param>
    void Register(AuthorityPluginRegistrationContext context);
}
