using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace WinnyProtocolAnalyzer
{
    static class Utility
    {
        /// <summary>
        /// byte 配列を比較します。
        /// </summary>
        /// <param name="aobArray1">byte 配列</param>
        /// <param name="aobArray2">byte 配列</param>
        /// <returns>比較結果</returns>
        static public bool ArrayEqual(byte[] aobArray1, byte[] aobArray2)
        {
            bool isEqual = false;
            if (aobArray1.Length == aobArray2.Length)
            {
                int i = 0;
                while ((i < aobArray2.Length) && (aobArray1[i] == aobArray2[i]))
                {
                    i += 1;
                }
                if (i == aobArray2.Length)
                {
                    isEqual = true;
                }
            }

            return isEqual;
        }


        /// <summary>
        /// byte 配列を16進数文字列に変換します。
        /// </summary>
        /// <param name="aobData">byte 配列</param>
        /// <returns>16進数文字列</returns>
        static public string ByteArrayToHexString(byte[] aobData)
        {
            return BitConverter.ToString(aobData).Replace("-", "");
        }

        /// <summary>
        /// 16進数文字列かどうかを検査します。
        /// </summary>
        /// <param name="sHash">16進数文字列</param>
        /// <returns>検査結果</returns>
        static public bool CheckHash(string sHash)
        {
            for (int i = 0; i < sHash.Length - 1; i = i + 2)
            {
                string sBuf = sHash.Substring(i, 2);
                if (!Regex.IsMatch(sBuf, @"^[0-9a-fA-F]{2}$"))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 文字列のチェックサムを計算します。
        /// </summary>
        /// <param name="sString">文字列</param>
        /// <returns>チェックサム</returns>
        static public short CalculateChecksum(string sString)
        {
            short iChecksum = 0;
            byte[] aobString = Encoding.Default.GetBytes(sString);
            foreach (byte bCharacter in aobString)
            {
                iChecksum += bCharacter;
            }

            return iChecksum;
        }

        /// <summary>
        /// 16進数文字列を byte 配列に変換します。
        /// </summary>
        /// <param name="sHexString">16進数文字列</param>
        /// <returns>byte 配列</returns>
        static public byte[] HexStringToByteArray(string sHexString)
        {
            bool isCorrect = true;
            List<byte> data = new List<byte>();

            for (int i = 0; i < sHexString.Length - 1; i = i + 2)
            {
                string sBuf = sHexString.Substring(i, 2);
                if (Regex.IsMatch(sBuf, @"^[0-9a-fA-F]{2}$"))
                {
                    data.Add(Convert.ToByte(sBuf, 16));
                }
                else
                {
                    isCorrect = false;
                }
            }

            if (isCorrect == false)
            {
                return null;
            }
            else
            {
                return data.ToArray();
            }
        }

        /// <summary>
        /// UNIX Timeを求める。
        /// </summary>
        /// <param name="Now">日付時刻</param>
        /// <returns>UNIX Time</returns>
        static public int UnixTime(DateTime Now)
        {
            TimeSpan ts = Now - new DateTime(1970, 1, 1, 0, 0, 0);
            return Convert.ToInt32(ts.TotalSeconds);
        }

        /// <summary>
        /// ファイル名として正しい文字列かを確認し、使用できない文字が入っている場合、"_"に置き換える
        /// </summary>
        /// <param name="s">ファイル名として正しいか確認する文字列</param>
        /// <returns>ファイル名として使用可能な文字列</returns>
        public static string ValidFileName(string s)
        {
            string valid = s;
            char[] invalidch = Path.GetInvalidFileNameChars();

            foreach (char c in invalidch)
            {
                valid = valid.Replace(c, '_');
            }
            return valid;
        }
    }
}
