using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace NetPanel.Help
{
    public static class ExtendHelper
    {
      

        /// <summary>
        /// 扩展帮助类
        /// </summary>

        #region int



     

        /// <summary>
        /// 转换指定时间得到对应的时间戳  
        /// true 则生成13位的时间戳,
        /// false 则生成10位的时间戳,默认为 true
        /// </summary>
        /// <param name="s"></param>
        /// <param name="isLongTime">精度（毫秒）设置 true，则生成13位的时间戳；精度（秒）设置为 false，则生成10位的时间戳；默认为 true </param>
        /// <returns>返回对应的时间戳</returns>
        public static long ToTimeStamp(this DateTime s, bool isLongTime = true)
        {
            var ts = s.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return isLongTime ? Convert.ToInt64(ts.TotalMilliseconds) : Convert.ToInt64(ts.TotalSeconds);
        }


        /// <summary>
        /// 取整 有小数进1
        /// </summary>
        /// <param name="d"></param>
        /// <param name="decimals"></param>
        /// <returns></returns>
        public static int ToInteger(this double d)
        {
            return Math.Ceiling(d).ToInt32();
        }

        /// <summary>
        /// 转换为Double 如果为空返回0
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static double ToDouble(this object s, double e = 0)
        {
            if (s == null || s == string.Empty)
            {
                return e;
            }
            return Convert.ToDouble(s);
        }
        /// <summary>
        /// 转换为int  如果为空返回0
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static int ToInt32(this object s, int e = 0)
        {
            if (s == null || s == string.Empty)
            {
                return e;
            }
            return Convert.ToInt32(s);
        }

        #endregion


        #region bool





        /// <summary>
        /// 判断 为空
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsNull(this string s)
        {
            return string.IsNullOrWhiteSpace(s);
        }


        /// <summary>
        /// 判断 不为空
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsNotNull(this string s)
        {
            return !string.IsNullOrWhiteSpace(s);
        }

        /// <summary>
        ///   判断是否 等于 字符串  true 包含   false 不包含   
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sArrStr"></param>
        /// <returns></returns>
        public static bool AndEquals(this string s, params string[] sArrStr)
        {
            for (int i = 0; i < sArrStr.Length; i++)
            {
                if (!s.Equals(sArrStr[i], StringComparison.OrdinalIgnoreCase))
                {
                    return false;
                }
            }
            return true;
        }


        /// <summary>
        ///   判断是否 包含等于 字符串  true 包含   false 不包含  
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sArrStr"></param>
        /// <returns></returns>
        public static bool OrEquals(this string s, params string[] sArrStr)
        {
            for (int i = 0; i < sArrStr.Length; i++)
            {
                if (s.Equals(sArrStr[i], StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }


        /// <summary>
        ///   判断是否 包含 字符串  true 包含   false 不包含   
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sArrStr"></param>
        /// <returns></returns>
        public static bool AndContains(this string s, params string[] sArrStr)
        {
            for (int i = 0; i < sArrStr.Length; i++)
            {
                if (s.IndexOf(sArrStr[i], StringComparison.OrdinalIgnoreCase) <= -1)
                {
                    return false;
                }
            }
            return true;
        }


        /// <summary>
        ///   判断是否 包含 字符串  true 包含   false 不包含  
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sArrStr"></param>
        /// <returns></returns>
        public static bool OrContains(this string s, params string[] sArrStr)
        {
            for (int i = 0; i < sArrStr.Length; i++)
            {
                if (s.IndexOf(sArrStr[i], StringComparison.OrdinalIgnoreCase) > -1)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region DateTime




        /// <summary>
        /// 字符串转换为 时间
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this object s)
        {
            return Convert.ToDateTime(s);
        }
        /// <summary>
        /// 字符串转换为 时间
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string s)
        {
            return Convert.ToDateTime(s);
        }
        /// <summary>
        /// 时间戳转为C#格式时间   
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        public static DateTime ToDateTimeByStamp(this string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime;
            if (timeStamp.Length.Equals(10))//判断是10位
            {
                lTime = long.Parse(timeStamp + "0000000");
            }
            else
            {
                lTime = long.Parse(timeStamp + "0000");//13位
            }
            TimeSpan toNow = new TimeSpan(lTime);
            DateTime daTime = dtStart.Add(toNow);
            return daTime;

        }
        #endregion

        #region double

        /// <summary>
        /// 带小数点数字匹配
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static double MatchingNumber(this string s)
        {
            string s1 = Regex.Replace(s, @"[^\d.\d]", "");
            if (s1.IsNotNull())
            {
                return s1.ToDouble();
            }
            return 0;
        }
        /// <summary>
        /// 保留小数点 不四舍五入
        /// </summary>
        /// <param name="d"></param>
        /// <param name="decimals"></param>
        /// <returns></returns>
        public static double NotRound(this double d, int decimals)
        {
            if (decimals == 0)
            {
                return (int)d;
            }
            string sStr = "1";
            for (int i = 0; i < decimals; i++)
            {
                sStr += "0";
            }
            decimals = Convert.ToInt32(sStr);
            return Math.Floor(d * decimals) / decimals;
        }

        /// <summary>
        /// 实现数据的四舍五入法
        /// </summary>
        /// <param name="v">要进行处理的数据</param>
        /// <param name="x">保留的小数位数</param>
        /// <returns>四舍五入后的结果</returns>
        public static double Round(this double v, int x)
        {
            bool isNegative = false;
            //如果是负数
            if (v < 0)
            {
                isNegative = true;
                v = -v;
            }
            int IValue = 1;
            for (int i = 1; i <= x; i++)
            {
                IValue = IValue * 10;
            }
            double Int = Math.Round(v * IValue + 0.5, 0);
            v = Int / IValue;

            if (isNegative)
            {
                v = -v;
            }
            return v;
        }

        /// <summary>
        /// 获取百分比 iCount=总数
        /// </summary>
        /// <param name="d"></param>
        /// <param name="iCount"></param>
        /// <returns></returns>
        public static double getProportion(this double d, double iCount)
        {

            try
            {
                double dc = Math.Round((d / iCount) * 100, 2);
                if (double.IsNaN(dc))
                {
                    return 0;
                }
                return dc;
            }
            catch (Exception)
            {
            }
            return 0;
        }

        /// <summary>
        /// 获取百分比 iCount=总数
        /// </summary>
        /// <param name="d"></param>
        /// <param name="iCount"></param>
        /// <returns></returns>
        public static double getProportion(this int d, double iCount)
        {

            try
            {
                double dc = Math.Round((d / iCount) * 100, 2);
                if (double.IsNaN(dc))
                {
                    return 0;
                }
                return dc;
            }
            catch (Exception)
            {
            }
            return 0;
        }


        /// <summary>
        /// 转换为 double
        /// </summary>
        /// <param name="d"></param>
        /// <param name="decimals"></param>
        /// <returns></returns>
        public static double ToDouble(this object d)
        {
            return Convert.ToDouble(d);
        }

        #endregion

        #region string



        /// <summary>
        /// 格式化ToString不会返回null
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string ToString(this object s, string e="")
        {
            if (s == null || s == string.Empty)
            {
                return e;
            }
            return s.ToString();
        }

        /// <summary>
        /// url 编码
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string UrlEncode(this object s, Encoding e = null)
        {
            if (e == null) e = Encoding.UTF8;
            return System.Web.HttpUtility.UrlEncode(s.ToString(), e);
        }

        /// <summary>
        /// url 解码
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string UrlDecode(this object s, Encoding e = null)
        {
            if (e == null) e = Encoding.UTF8;
            return System.Web.HttpUtility.UrlDecode(s.ToString(), e);
        }

        /// <summary>
        /// 数字 千位分隔符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ToThousandsSeparator(this double s)
        {
            return s.ToString("N0");
        }

        /// <summary>
        /// 数字 千位分隔符
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ToThousandsSeparator(this int s)
        {
            return s.ToString("N0");
        }


        /// <summary>  
        /// 将c# DateTime时间格式转换为Unix时间戳格式   13位
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns>long</returns>  
        public static string ToTimeStamp13(this System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t.ToString();
        }
        /// <summary>  
        /// 将c# DateTime时间格式转换为Unix时间戳格式   10位
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns>long</returns>  
        public static string ToTimeStamp10(this System.DateTime time)
        {
            DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
            int timeStamp = Convert.ToInt32((time - dateStart).TotalSeconds);
            return timeStamp.ToString(); ;
        }



        /// <summary>
        /// 截取字符串 过滤空格
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string[] SplitRemoveEmptyEntries(this string s, params string[] arr)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(s))
                {
                    return new string[] { };
                }
                return s.Split(arr, StringSplitOptions.RemoveEmptyEntries);
            }
            catch (Exception)
            {
                return new string[] { };
            }
        }

        /// <summary>
        /// 过滤sql 特殊符号
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReplaceSQLChar(this string str)
        {
            if (str == String.Empty)
                return String.Empty;
            str = str.Replace("'", "");
            str = str.Replace("<", "");
            str = str.Replace(">", "");
            str = str.Replace("@", "");
            str = str.Replace("=", "");
            str = str.Replace("+", "");
            str = str.Replace("*", "");
            str = str.Replace("&", "");
            str = str.Replace("#", "");
            str = str.Replace("%", "");
            str = str.Replace("$", "");

            //删除与数据库相关的词
            str = Regex.Replace(str, "select", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "insert", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "delete from", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "count", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "drop table", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "asc", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "mid", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "char", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "xp_cmdshell", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "exec master", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "net localgroup administrators", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "and", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "net user", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "or", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "net", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "-", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "delete", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "drop", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "script", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "update", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "and", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "chr", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "master", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "declare", "", RegexOptions.IgnoreCase);
            str = Regex.Replace(str, "mid", "", RegexOptions.IgnoreCase);

            return str;
        }


        /// <summary>
        /// 将DateTime 格式转换为 yyyy-MM-dd HH:mm:ss
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ToDateStr(this DateTime d)
        {
            return d.ToString("yyyy-MM-dd HH:mm:ss");
        }
        /// <summary>
        /// 将DateTime 格式转换为 yyyy-MM-dd HH:mm:ss
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ToDateStr(this DateTime? d)
        {
            return Convert.ToDateTime(d).ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// Md5 加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetMD5Hash(this string str)
        {
            using (MD5 mi = MD5.Create())
            {
                byte[] buffer = Encoding.Default.GetBytes(str);
                //开始加密
                byte[] newBuffer = mi.ComputeHash(buffer);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < newBuffer.Length; i++)
                {
                    sb.Append(newBuffer[i].ToString("x2"));
                }
                return sb.ToString();
            }
        }

        #endregion

        #region T
        /// <summary>
        /// 对象拷贝
        /// </summary>
        /// <param name="obj">被复制对象</param>
        /// <returns>新对象</returns>
        public static T CopyOjbect<T>(T obj)
        {
            Object targetDeepCopyObj = null;
            if ((T)obj == null)
            {
                return (T)targetDeepCopyObj;
            }
            Type targetType = obj.GetType();
            //值类型  
            if (targetType.IsValueType == true)
            {
                targetDeepCopyObj = obj;
            }
            //引用类型   
            else
            {
                targetDeepCopyObj = System.Activator.CreateInstance(targetType);   //创建引用对象   
                System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();

                foreach (System.Reflection.MemberInfo member in memberCollection)
                {
                    //拷贝字段
                    if (member.MemberType == System.Reflection.MemberTypes.Field)
                    {
                        System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
                        Object fieldValue = field.GetValue(obj);
                        if (fieldValue is ICloneable)
                        {
                            field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
                        }
                        else
                        {
                            field.SetValue(targetDeepCopyObj, CopyOjbect(fieldValue));
                        }

                    }//拷贝属性
                    else if (member.MemberType == System.Reflection.MemberTypes.Property)
                    {
                        System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;

                        MethodInfo info = myProperty.GetSetMethod(false);
                        if (info != null)
                        {
                            try
                            {
                                object propertyValue = myProperty.GetValue(obj, null);
                                if (propertyValue is ICloneable)
                                {
                                    myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
                                }
                                else
                                {
                                    myProperty.SetValue(targetDeepCopyObj, CopyOjbect(propertyValue), null);
                                }
                            }
                            catch (System.Exception ex)
                            {

                            }
                        }
                    }
                }
            }
            return (T)targetDeepCopyObj;

        }
        #endregion

    }

}
