using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using StellaOps.Auth.Client;

namespace StellaOps.Scanner.Core.Security;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddScannerAuthorityCore(
        this IServiceCollection services,
        Action<StellaOpsAuthClientOptions> configureAuthority,
        Action<DpopValidationOptions>? configureDpop = null)
    {
        ArgumentNullException.ThrowIfNull(services);
        ArgumentNullException.ThrowIfNull(configureAuthority);

        services.AddStellaOpsAuthClient(configureAuthority);

        if (configureDpop is not null)
        {
            services.AddOptions<DpopValidationOptions>().Configure(configureDpop).PostConfigure(static options => options.Validate());
        }
        else
        {
            services.AddOptions<DpopValidationOptions>().PostConfigure(static options => options.Validate());
        }

        services.TryAddSingleton<IDpopReplayCache>(provider => new InMemoryDpopReplayCache(provider.GetService<TimeProvider>()));
        services.TryAddSingleton<IDpopProofValidator, DpopProofValidator>();
        services.TryAddSingleton<IAuthorityTokenSource, AuthorityTokenSource>();
        services.TryAddSingleton<IPluginCatalogGuard, RestartOnlyPluginGuard>();

        return services;
    }
}
