using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.ReverseProxy
{
    /// 
    /// HttpClient工厂
    /// 
    sealed class HttpClientFactory
    {
        private HttpClientHanlder httpClientHanlder;
        /// 
        /// HttpClient工厂
        /// 
        /// 
        /// 
        public HttpClientFactory(
            DomainResolver domainResolver,
            IOptionsMonitor options)
        {
            this.httpClientHanlder = new HttpClientHanlder(domainResolver);
            options.OnChange(opt => this.httpClientHanlder = new HttpClientHanlder(domainResolver));
        }
        /// 
        /// 创建httpClient
        /// 
        /// 
        /// 
        public HttpMessageInvoker CreateHttpClient(DomainConfig domainConfig)
        {
            return new HttpClient(this.httpClientHanlder, domainConfig, disposeHandler: false);
        }
        /// 
        /// http客户端
        /// 
        private class HttpClient : HttpMessageInvoker
        {
            private readonly DomainConfig domainConfig;
            public HttpClient(
                HttpMessageHandler handler,
                DomainConfig domainConfig,
                bool disposeHandler = false) : base(handler, disposeHandler)
            {
                this.domainConfig = domainConfig;
            }
            /// 
            /// 发送数据
            /// 
            /// 
            /// 
            /// 
            public override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                request.SetRequestContext(new RequestContext
                {
                    Host = request.RequestUri?.Host,
                    IsHttps = request.RequestUri?.Scheme == Uri.UriSchemeHttps,
                    TlsSniPattern = this.domainConfig.GetTlsSniPattern(),
                    TlsIgnoreNameMismatch = this.domainConfig.TlsIgnoreNameMismatch
                });
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
}