using DNS.Server;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.Dns
{
    /// 
    /// dns后台服务
    /// 
    sealed class DnsHostedService : IHostedService
    {
        private readonly DnsServer dnsServer;
        private readonly IOptions options;
        private readonly ILogger logger;
        private IPAddress[]? dnsAddresses;
        /// 
        /// dns后台服务
        /// 
        /// 
        /// 
        /// 
        public DnsHostedService(
            GithubRequestResolver githubRequestResolver,
            IOptions options,
            ILogger logger)
        {
            this.dnsServer = new DnsServer(githubRequestResolver, options.Value.UpStream);
            this.options = options;
            this.logger = logger;
        }
        /// 
        /// 启动dns服务
        /// 
        /// 
        /// 
        public Task StartAsync(CancellationToken cancellationToken)
        {
            this.dnsServer.Listen();
            this.logger.LogInformation("dns服务启动成功");
            this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, this.options.Value.UpStream);
            return Task.CompletedTask;
        }
        /// 
        /// 停止dns服务
        /// 
        /// 
        /// 
        public Task StopAsync(CancellationToken cancellationToken)
        {
            this.dnsServer.Dispose();
            this.logger.LogInformation("dns服务已终止");
            if (this.dnsAddresses != null)
            {
                this.SetNameServers(this.dnsAddresses);
            }
            return Task.CompletedTask;
        }
        /// 
        /// 设置dns
        /// 
        /// 
        /// 
        private IPAddress[]? SetNameServers(params IPAddress[] nameServers)
        {
            if (this.options.Value.SetToLocalMachine && OperatingSystem.IsWindows())
            {
                try
                {
                    var results = NameServiceUtil.SetNameServers(nameServers);
                    this.logger.LogInformation($"设置本机dns成功");
                    return results;
                }
                catch (Exception ex)
                {
                    this.logger.LogWarning($"设置本机dns失败:{ex.Message}");
                }
            }
            return default;
        }
    }
}