using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using StellaOps.Feedser.Source.Cccs.Configuration;
using StellaOps.Feedser.Source.Cccs.Internal;
using StellaOps.Feedser.Source.Common.Http;
using StellaOps.Feedser.Source.Common.Html;

namespace StellaOps.Feedser.Source.Cccs;

public static class CccsServiceCollectionExtensions
{
    public static IServiceCollection AddCccsConnector(this IServiceCollection services, Action<CccsOptions> configure)
    {
        ArgumentNullException.ThrowIfNull(services);
        ArgumentNullException.ThrowIfNull(configure);

        services.AddOptions<CccsOptions>()
            .Configure(configure)
            .PostConfigure(static options => options.Validate());

        services.AddSourceHttpClient(CccsOptions.HttpClientName, static (sp, clientOptions) =>
        {
            var options = sp.GetRequiredService<IOptions<CccsOptions>>().Value;
            clientOptions.UserAgent = "StellaOps.Feedser.Cccs/1.0";
            clientOptions.Timeout = options.RequestTimeout;
            clientOptions.AllowedHosts.Clear();

            foreach (var feed in options.Feeds.Where(static feed => feed.Uri is not null))
            {
                clientOptions.AllowedHosts.Add(feed.Uri!.Host);
            }

            clientOptions.AllowedHosts.Add("www.cyber.gc.ca");
            clientOptions.AllowedHosts.Add("cyber.gc.ca");
        });

        services.TryAddSingleton<HtmlContentSanitizer>();
        services.TryAddSingleton<CccsDiagnostics>();
        services.TryAddSingleton<CccsHtmlParser>();
        services.TryAddSingleton<CccsFeedClient>();
        services.AddTransient<CccsConnector>();
        return services;
    }
}
