using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Feedser.Core.Jobs;
using StellaOps.Feedser.Source.Ghsa.Configuration;

namespace StellaOps.Feedser.Source.Ghsa;

public sealed class GhsaDependencyInjectionRoutine : IDependencyInjectionRoutine
{
    private const string ConfigurationSection = "feedser:sources:ghsa";
    private const string FetchCron = "1,11,21,31,41,51 * * * *";
    private const string ParseCron = "3,13,23,33,43,53 * * * *";
    private const string MapCron = "5,15,25,35,45,55 * * * *";

    private static readonly TimeSpan FetchTimeout = TimeSpan.FromMinutes(6);
    private static readonly TimeSpan ParseTimeout = TimeSpan.FromMinutes(5);
    private static readonly TimeSpan MapTimeout = TimeSpan.FromMinutes(5);
    private static readonly TimeSpan LeaseDuration = TimeSpan.FromMinutes(4);

    public IServiceCollection Register(IServiceCollection services, IConfiguration configuration)
    {
        ArgumentNullException.ThrowIfNull(services);
        ArgumentNullException.ThrowIfNull(configuration);

        services.AddGhsaConnector(options =>
        {
            configuration.GetSection(ConfigurationSection).Bind(options);
            options.Validate();
        });

        var scheduler = new JobSchedulerBuilder(services);
        scheduler
            .AddJob<GhsaFetchJob>(
                GhsaJobKinds.Fetch,
                cronExpression: FetchCron,
                timeout: FetchTimeout,
                leaseDuration: LeaseDuration)
            .AddJob<GhsaParseJob>(
                GhsaJobKinds.Parse,
                cronExpression: ParseCron,
                timeout: ParseTimeout,
                leaseDuration: LeaseDuration)
            .AddJob<GhsaMapJob>(
                GhsaJobKinds.Map,
                cronExpression: MapCron,
                timeout: MapTimeout,
                leaseDuration: LeaseDuration);

        return services;
    }
}
