using DNS.Client.RequestResolver;
using DNS.Protocol;
using DNS.Protocol.ResourceRecords;
using FastGithub.Configuration;
using System;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.Dns
{
    /// 
    /// dns解析者
    ///  
    sealed class RequestResolver : IRequestResolver
    {
        private readonly TimeSpan ttl = TimeSpan.FromMinutes(1d);
        private readonly FastGithubConfig fastGithubConfig;
        /// 
        /// dns解析者
        /// 
        /// 
        public RequestResolver(FastGithubConfig fastGithubConfig)
        {
            this.fastGithubConfig = fastGithubConfig;
        }
        /// 
        /// 解析域名
        /// 
        /// 
        /// 
        /// 
        public async Task Resolve(IRequest request, CancellationToken cancellationToken = default)
        {
            var response = Response.FromRequest(request);
            if (request is not RemoteEndPointRequest remoteEndPointRequest)
            {
                return response;
            }
            var question = request.Questions.FirstOrDefault();
            if (question == null || question.Type != RecordType.A)
            {
                return response;
            }
            // 解析匹配的域名指向本机ip
            var domain = question.Name;
            if (this.fastGithubConfig.IsMatch(domain.ToString()) == true)
            {
                var localAddress = remoteEndPointRequest.GetLocalIPAddress() ?? IPAddress.Loopback;
                var record = new IPAddressResourceRecord(domain, localAddress, this.ttl);
                response.AnswerRecords.Add(record);
                return response;
            }
            // 使用回退dns解析域名
            foreach (var dns in this.fastGithubConfig.FallbackDns)
            {
                try
                {
                    var resolver = new UdpRequestResolver(dns);
                    return await resolver.Resolve(request, cancellationToken);
                }
                catch (Exception)
                {
                }
            }
            throw new FastGithubException($"无法解析域名{domain}");
        }
    }
}