using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Mall.Common
{
    /// <summary>
    /// 类型转换帮助类
    /// </summary>
    public class ConvertHelper
    {

        /// <summary>
        /// 转换字符流成字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToString(byte[] bytes)
        {
            var sb = new StringBuilder(64);
            foreach (byte iByte in bytes) sb.AppendFormat("{0:x2}", iByte);
            return sb.ToString();
        }

        /// <summary>
        /// 转换成Byte数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] ToBytes(string hexString)
        {
            if (hexString == null) return null;
            var data = new byte[hexString.Length / 2];
            int h, l;
            for (var i = 0; i < data.Length; i++)
            {
                h = (hexString[2 * i] > 57 ? hexString[2 * i] - 'A' + 10 : hexString[2 * i] - '0') << 4 & 0x000000F0;
                l = (hexString[2 * i + 1] > 57 ? hexString[2 * i + 1] - 'A' + 10 : hexString[2 * i + 1] - '0') & 0x0000000F;

                data[i] = (byte)(h | l);
            }

            return data;
        }
        
        /// <summary>
        /// 类型转换
        /// </summary>
        /// <typeparam name="T">要转换类型</typeparam>
        /// <param name="obj">要转换的值</param>
        /// <returns></returns>
        public static T ConvertTo<T>(object obj)
        {
            if (obj == null) return default(T);//返回默认值
            Type tp = typeof(T);
            //泛型Nullable判断，取其中的类型
            if (tp.IsGenericType)
            {
                tp = tp.GetGenericArguments()[0];
            }
            //string直接返回转换
            if (tp.Name.ToLower() == "string")
            {
                return (T)obj;
            }
            //反射获取TryParse方法
            var TryParse = tp.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,
                                            new Type[] { typeof(string), tp.MakeByRefType() },
                                            new ParameterModifier[] { new ParameterModifier(2) });
            var parameters = new object[] { obj, Activator.CreateInstance(tp) };
            try
            {
                bool success = (bool)TryParse.Invoke(null, parameters);
                //成功返回转换后的值，否则返回类型的默认值
                if (success)
                {
                    return (T)parameters[1];
                }
                return default(T);
            }
            catch
            {
                return default(T);
            }
        }

        /// <summary>
        /// 转Int
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int ConvertInt(object obj)
        {
            return ConvertTo<int>(obj);
        }

        /// <summary>
        /// 转Int
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static int ToInt(object obj,int defaultValue=0)
        {
            int result = defaultValue;
            if (obj != null)
            {
                Int32.TryParse(obj.ToString(), out result);
            }
            return result;
        }
    }
}

