using System.ComponentModel.DataAnnotations;
using System.Net.Http.Headers;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using StellaOps.Excititor.Connectors.Cisco.CSAF.Configuration;
using StellaOps.Excititor.Connectors.Cisco.CSAF.Metadata;
using StellaOps.Excititor.Connectors.Abstractions;
using StellaOps.Excititor.Core;
using System.IO.Abstractions;

namespace StellaOps.Excititor.Connectors.Cisco.CSAF.DependencyInjection;

public static class CiscoConnectorServiceCollectionExtensions
{
    public static IServiceCollection AddCiscoCsafConnector(this IServiceCollection services, Action<CiscoConnectorOptions>? configure = null)
    {
        ArgumentNullException.ThrowIfNull(services);

        services.AddOptions<CiscoConnectorOptions>()
            .Configure(options =>
            {
                configure?.Invoke(options);
            })
            .PostConfigure(options =>
            {
                Validator.ValidateObject(options, new ValidationContext(options), validateAllProperties: true);
            });

        services.TryAddSingleton<IMemoryCache, MemoryCache>();
        services.TryAddSingleton<IFileSystem, FileSystem>();
        services.TryAddEnumerable(ServiceDescriptor.Singleton<IVexConnectorOptionsValidator<CiscoConnectorOptions>, CiscoConnectorOptionsValidator>());

        services.AddHttpClient(CiscoConnectorOptions.HttpClientName)
            .ConfigureHttpClient((provider, client) =>
            {
                var options = provider.GetRequiredService<IOptions<CiscoConnectorOptions>>().Value;
                client.Timeout = TimeSpan.FromSeconds(30);
                client.DefaultRequestHeaders.Accept.ParseAdd("application/json");
                if (!string.IsNullOrWhiteSpace(options.ApiToken))
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", options.ApiToken);
                }
            });

        services.AddSingleton<CiscoProviderMetadataLoader>();
        services.AddSingleton<IVexConnector, CiscoCsafConnector>();

        return services;
    }
}
