using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace WinnyProtocolAnalyzer
{
    static class Domains
    {
        const int iDomainWeight = 64;
        const int iDomainPriorityWeight = 100;
        const int iLineSpeedPriorityWeight = 1;
        const int iClusterPriorityWeight = 1000;

        /// <summary>
        /// ドメイン閾値を計算します。
        /// </summary>
        /// <param name="sLocalEndPoint">ローカルエンドポイント</param>
        /// <returns>ドメイン閾値</returns>
        static public int CalculateLinkPointThreshold(string sLocalEndPoint)
        {
            int iThreshold = 0;

            // 2nd Level Domain Judgement
            if (Regex.IsMatch(sLocalEndPoint, @"\w*(\.or\.|\.ne\.|\.ad\.|\.co\.|\.ac\.|\.com\.|\.org\.|\.net\.|\.info\.|\.biz\.)\w*") == true)
            {
                iThreshold = iDomainWeight * 2; // ex) .ocn.ne.jp
            }
            else
            {
                iThreshold = iDomainWeight * 1; // ex) bbtec.net, bbexcite.jp
            }

            return iThreshold;
        }


        /// <summary>
        /// IPアドレス文字列からFQDNを取得する
        /// </summary>
        /// <param name="sIPAddress">IPアドレス文字列</param>
        /// <param name="useLookUp">DNSを引きにいくか</param>
        /// <returns>FQDN</returns>
        static public String GetNodeEndPoint(string sIPAddress, bool useLookUp)
        {
            try
            {
                IPAddress ipAddress = IPAddress.Parse(sIPAddress);
                return GetNodeEndPoint(ipAddress, useLookUp);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception caught (IntelliSense - GetNodeEndPoint)");
                Debug.WriteLine(string.Format("Source: {0}", ex.Source));
                Debug.WriteLine(string.Format("Message: {0}", ex.Message));
                Debug.WriteLine(string.Format("StackTrace: {0}", ex.StackTrace));
            }
            return sIPAddress;
        }

        /// <summary>
        /// IPアドレスバイト配列からFQDNを取得する
        /// </summary>
        /// <param name="aobIPAddress">IPアドレスバイト配列</param>
        /// <param name="useLookUp">DNSを引きにいくか</param>
        /// <returns>FQDN</returns>
        static public String GetNodeEndPoint(byte[] aobIPAddress, bool useLookUp)
        {
            try
            {
                IPAddress ipAddress = new IPAddress(aobIPAddress);
                return GetNodeEndPoint(ipAddress, useLookUp);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception caught (IntelliSense - GetNodeEndPoint)");
                Debug.WriteLine(string.Format("Source: {0}", ex.Source));
                Debug.WriteLine(string.Format("Message: {0}", ex.Message));
                Debug.WriteLine(string.Format("StackTrace: {0}", ex.StackTrace));
            }
            return "";
        }

        /// <summary>
        /// IPアドレスからFQDNを取得する
        /// </summary>
        /// <param name="ipAddress">IPアドレス</param>
        /// <param name="useLookUp">DNSを引きにいくか</param>
        /// <returns>FQDN</returns>
        static public String GetNodeEndPoint(IPAddress ipAddress, bool useLookUp)
        {
            try
            {
                string sResult = Dns.GetHostEntry(ipAddress).HostName;
                IPAddress ipParsed;
                if (sResult == "" || IPAddress.TryParse(sResult, out ipParsed) == true)
                {
                    if (useLookUp)
                    {
                        return NameServerLookup(ipAddress);
                    }
                }
                return sResult;
            }
            catch
            {
                if (useLookUp)
                {
                    return NameServerLookup(ipAddress);
                }
                else
                {
                    return ipAddress.ToString();
                }
            }
        }
        #region GetNodeInfo Error Processing
        static private String NameServerLookup(IPAddress ipAddress)
        {
            Process p = new Process();
            p.StartInfo.FileName = @"C:\Windows\System32\nslookup.exe";
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
            p.StartInfo.RedirectStandardInput = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.WorkingDirectory = @"C:\";
            p.StartInfo.Arguments = String.Format(@"{0}", ipAddress);
            p.Start();
            p.WaitForExit();
            string sResult = p.StandardOutput.ReadToEnd();

            return ParseResult(sResult, ipAddress);
        }

        static private String ParseResult(string sResult, IPAddress ipAddress)
        {
            try
            {
                string[] sLines = sResult.Split('\n');
                for (int i = 0; i < sLines.Length; i++)
                {
                    if (sLines[i].StartsWith("Name"))
                    {
                        return sLines[i].Substring(5, sLines[i].Length - 5).Replace(" ", "");
                    }
                    if (sLines[i].StartsWith("名前"))
                    {
                        return sLines[i].Substring(4, sLines[i].Length - 4).Replace(" ", "");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception caught (IntelliSense - ParseResult)");
                Debug.WriteLine(string.Format("Source: {0}", ex.Source));
                Debug.WriteLine(string.Format("Message: {0}", ex.Message));
                Debug.WriteLine(string.Format("StackTrace: {0}", ex.StackTrace));
            }

            return ipAddress.ToString();
        }
        #endregion


    }
}
