using System;
using System.Net;
using System.Net.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using StellaOps.Excititor.Connectors.Abstractions;
using StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Configuration;
using StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Fetch;
using StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Discovery;
using StellaOps.Excititor.Core;
using System.IO.Abstractions;

namespace StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.DependencyInjection;

public static class OciOpenVexAttestationConnectorServiceCollectionExtensions
{
    public static IServiceCollection AddOciOpenVexAttestationConnector(
        this IServiceCollection services,
        Action<OciOpenVexAttestationConnectorOptions>? configure = null)
    {
        ArgumentNullException.ThrowIfNull(services);

        services.TryAddSingleton<IMemoryCache, MemoryCache>();
        services.TryAddSingleton<IFileSystem, FileSystem>();

        services.AddOptions<OciOpenVexAttestationConnectorOptions>()
            .Configure(options =>
            {
                configure?.Invoke(options);
            });

        services.AddSingleton<IVexConnectorOptionsValidator<OciOpenVexAttestationConnectorOptions>, OciOpenVexAttestationConnectorOptionsValidator>();
        services.AddSingleton<OciAttestationDiscoveryService>();
        services.AddSingleton<OciAttestationFetcher>();
        services.AddSingleton<IVexConnector, OciOpenVexAttestationConnector>();

        services.AddHttpClient(OciOpenVexAttestationConnectorOptions.HttpClientName, client =>
            {
                client.Timeout = TimeSpan.FromSeconds(30);
                client.DefaultRequestHeaders.UserAgent.ParseAdd("StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest/1.0");
                client.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.cncf.openvex.v1+json");
                client.DefaultRequestHeaders.Accept.ParseAdd("application/json");
            })
            .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.All,
            });

        return services;
    }
}
