using FastGithub.Scanner;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Net.Sockets;
namespace FastGithub
{
    /// 
    /// 服务注册扩展
    /// 
    public static class ScannerServiceCollectionExtensions
    {
        /// 
        /// 注册程序集下所有服务下选项
        /// 
        /// 
        /// 配置  
        /// 
        public static IServiceCollection AddGithubScanner(this IServiceCollection services, IConfiguration configuration)
        {
            var assembly = typeof(ScannerServiceCollectionExtensions).Assembly;
            var defaultUserAgent = new ProductInfoHeaderValue(assembly.GetName().Name ?? nameof(FastGithub), assembly.GetName().Version?.ToString());
            services
                .AddHttpClient(nameof(Scanner))
                .SetHandlerLifetime(TimeSpan.FromMinutes(5d))
                .AddHttpMessageHandler()
                .ConfigureHttpClient(httpClient =>
                {
                    httpClient.Timeout = TimeSpan.FromSeconds(10d);
                    httpClient.DefaultRequestHeaders.Accept.TryParseAdd("*/*");
                    httpClient.DefaultRequestHeaders.UserAgent.Add(defaultUserAgent);
                })
                .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
                {
                    Proxy = null,
                    UseProxy = false,
                    AllowAutoRedirect = false,
                    ConnectCallback = async (ctx, ct) =>
                    {
                        var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                        await socket.ConnectAsync(ctx.DnsEndPoint, ct);
                        var stream = new NetworkStream(socket, ownsSocket: true);
                        if (ctx.InitialRequestMessage.Headers.Host == null)
                        {
                            return stream;
                        }
                        var sslStream = new SslStream(stream, leaveInnerStreamOpen: false, delegate { return true; });
                        await sslStream.AuthenticateAsClientAsync(string.Empty, null, false);
                        return sslStream;
                    }
                });
            return services
                .AddMemoryCache()
                .AddServiceAndOptions(assembly, configuration)
                .AddHostedService()
                .AddHostedService()
                .AddSingleton(appService => appService.GetRequiredService());
            ;
        }
    }
}