using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace CommonLang.Net
{
    public static class IPUtil
    {
        //         public static IPEndPoint ToEndPoint(Uri uri)
        //         {
        //             IPAddress[] ip = Dns.GetHostAddresses(uri.Host);
        //             IPEndPoint ret = new IPEndPoint(ip[0], uri.Port);
        //             return ret;
        //         }
        //         public static IPEndPoint ToEndPoint(string host, int port)
        //         {
        //             IPAddress[] ip = Dns.GetHostAddresses(host);
        //             IPEndPoint ret = new IPEndPoint(ip[0], port);
        //             return ret;
        //         }
        public static IPAddress ToExpectAddress(string host, AddressFamily family)
        {
            IPAddress[] ips = Dns.GetHostAddresses(host);
            foreach (var ip in ips)
            {
                if (ip.AddressFamily == family)
                {
                    return ip;
                }
            }
            return null;
        }

        /// <summary>
        /// 用System.net.dns类中的GetHostEntry()和GetHostName()方法来建立一个本
        /// 地IP地址,并且建立了一个IPHostEntry对象。用以下两句代码来获取本地IP
        /// 地址
        /// </summary>
        /// <returns></returns>
        public static IPEndPoint CreateLocalConnectorEndPoint()
        {
            return new IPEndPoint(IPAddress.IPv6Any, 0);
        }

        public static IPEndPoint CreateLocalListenEndPoint(int port)
        {
            return new IPEndPoint(IPAddress.IPv6Any, port);
        }


        public static bool IsOnlyIPv6(IPHostEntry ips)
        {
            if (ips.AddressList.Length == 0)
            {
                return false;
            }
            foreach (var ip in ips.AddressList)
            {
                if (ip.AddressFamily != AddressFamily.InterNetworkV6)
                {
                    return false;
                }
            }
            return true;
        }

        public static IPAddress MapToIPv6(this IPAddress addr)
        {
            if (addr.AddressFamily != AddressFamily.InterNetwork)
                throw new ArgumentException("Must pass an IPv4 address to MapToIPv6");

            string ipv4str = addr.ToString();

            return IPAddress.Parse("::ffff:" + ipv4str);
        }
        public static IPAddress MapToIPv6(this string ipv4str)
        {
            return IPAddress.Parse("::ffff:" + ipv4str);
        }

        public static bool IsIPv4MappedToIPv6(this IPAddress addr)
        {
            bool pass1 = addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6, pass2;

            try
            {
                pass2 = (addr.ToString().StartsWith("0000:0000:0000:0000:0000:ffff:") ||
                        addr.ToString().StartsWith("0:0:0:0:0:ffff:") ||
                        addr.ToString().StartsWith("::ffff:")) &&
                        IPAddress.Parse(addr.ToString().Substring(addr.ToString().LastIndexOf(":") + 1)).AddressFamily == AddressFamily.InterNetwork;
            }
            catch
            {
                return false;
            }

            return pass1 && pass2;
        }

    }
}