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

namespace StellaOps.Feedser.Source.Ru.Nkcki;

public sealed class RuNkckiDependencyInjectionRoutine : IDependencyInjectionRoutine
{
    private const string ConfigurationSection = "feedser:sources:ru-nkcki";

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

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

        services.AddTransient<RuNkckiFetchJob>();
        services.AddTransient<RuNkckiParseJob>();
        services.AddTransient<RuNkckiMapJob>();

        services.PostConfigure<JobSchedulerOptions>(options =>
        {
            EnsureJob(options, RuNkckiJobKinds.Fetch, typeof(RuNkckiFetchJob));
            EnsureJob(options, RuNkckiJobKinds.Parse, typeof(RuNkckiParseJob));
            EnsureJob(options, RuNkckiJobKinds.Map, typeof(RuNkckiMapJob));
        });

        return services;
    }

    private static void EnsureJob(JobSchedulerOptions schedulerOptions, string kind, Type jobType)
    {
        if (schedulerOptions.Definitions.ContainsKey(kind))
        {
            return;
        }

        schedulerOptions.Definitions[kind] = new JobDefinition(
            kind,
            jobType,
            schedulerOptions.DefaultTimeout,
            schedulerOptions.DefaultLeaseDuration,
            CronExpression: null,
            Enabled: true);
    }
}
