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

namespace StellaOps.Feedser.Source.Acsc;

public sealed class AcscDependencyInjectionRoutine : IDependencyInjectionRoutine
{
    private const string ConfigurationSection = "feedser:sources:acsc";

    private const string FetchCron = "7,37 * * * *";
    private const string ParseCron = "12,42 * * * *";
    private const string MapCron = "17,47 * * * *";
    private const string ProbeCron = "25,55 * * * *";

    private static readonly TimeSpan FetchTimeout = TimeSpan.FromMinutes(4);
    private static readonly TimeSpan ParseTimeout = TimeSpan.FromMinutes(3);
    private static readonly TimeSpan MapTimeout = TimeSpan.FromMinutes(3);
    private static readonly TimeSpan ProbeTimeout = TimeSpan.FromMinutes(1);
    private static readonly TimeSpan LeaseDuration = TimeSpan.FromMinutes(3);

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

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

        var scheduler = new JobSchedulerBuilder(services);
        scheduler
            .AddJob<AcscFetchJob>(AcscJobKinds.Fetch, FetchCron, FetchTimeout, LeaseDuration)
            .AddJob<AcscParseJob>(AcscJobKinds.Parse, ParseCron, ParseTimeout, LeaseDuration)
            .AddJob<AcscMapJob>(AcscJobKinds.Map, MapCron, MapTimeout, LeaseDuration)
            .AddJob<AcscProbeJob>(AcscJobKinds.Probe, ProbeCron, ProbeTimeout, LeaseDuration);

        return services;
    }
}
