using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace FastGithub.Dns
{
    /// 
    /// 系统域名服务工具
    /// 
    [SupportedOSPlatform("windows")]
    static class SystemDnsUtil
    {
        /// 
        /// www.baidu.com的ip
        /// 
        private static readonly IPAddress www_baidu_com = IPAddress.Parse("183.232.231.172");
        [DllImport("iphlpapi")]
        private static extern int GetBestInterface(uint dwDestAddr, ref uint pdwBestIfIndex);
        /// 
        /// 刷新DNS缓存
        /// 
        [DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCache", SetLastError = true)]
        public static extern void DnsFlushResolverCache();
        /// 
        /// 通过远程地址查找匹配的网络适接口
        /// 
        /// 
        /// 
        private static NetworkInterface GetBestNetworkInterface(IPAddress remoteAddress)
        {
            var dwBestIfIndex = 0u;
            var dwDestAddr = BitConverter.ToUInt32(remoteAddress.GetAddressBytes());
            var errorCode = GetBestInterface(dwDestAddr, ref dwBestIfIndex);
            if (errorCode != 0)
            {
                throw new NetworkInformationException(errorCode);
            }
            var @interface = NetworkInterface
                .GetAllNetworkInterfaces()
                .Where(item => item.GetIPProperties().GetIPv4Properties().Index == dwBestIfIndex)
                .FirstOrDefault();
            return @interface ?? throw new NotSupportedException("找不到网络适配器用来设置dns");
        }
        /// 
        /// 设置主dns
        /// 
        /// 
        /// 
        ///  
        public static void DnsSetPrimitive(IPAddress primitive)
        {
            var @interface = GetBestNetworkInterface(www_baidu_com);
            var dnsAddresses = @interface.GetIPProperties().DnsAddresses;
            if (primitive.Equals(dnsAddresses.FirstOrDefault()) == false)
            {
                var nameServers = dnsAddresses.Prepend(primitive);
                SetNameServers(@interface, nameServers);
            }
        }
        /// 
        /// 移除主dns
        /// 
        /// 
        /// 
        ///  
        public static void DnsRemovePrimitive(IPAddress primitive)
        {
            var @interface = GetBestNetworkInterface(www_baidu_com);
            var dnsAddresses = @interface.GetIPProperties().DnsAddresses;
            if (primitive.Equals(dnsAddresses.FirstOrDefault()))
            {
                var nameServers = dnsAddresses.Skip(1);
                SetNameServers(@interface, nameServers);
            }
        }
        /// 
        /// 设置网口的dns
        /// 
        /// 
        /// 
        private static void SetNameServers(NetworkInterface @interface, IEnumerable nameServers)
        {
            Netsh($@"interface ipv4 delete dns ""{@interface.Name}"" all");
            foreach (var address in nameServers)
            {
                Netsh($@"interface ipv4 add dns ""{@interface.Name}"" {address} validate=no");
            }
            static void Netsh(string arguments)
            {
                var netsh = new ProcessStartInfo
                {
                    FileName = "netsh.exe",
                    Arguments = arguments,
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Hidden
                };
                Process.Start(netsh)?.WaitForExit();
            }
        }
    }
}