using FastJSON;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using Top.Api.Parser;
namespace Top.Api.Util
{
    /// 
    /// TOP系统工具类。
    /// 
    public abstract class TopUtils
    {
        private static readonly JSONParameters jp = new JSONParameters();
        private static string intranetIp;
        static TopUtils()
        {
            jp.UseApiNamingStyle = true;
            jp.UseExtensions = false;
            jp.SerializeNullValues = false;
        }
        /// 
        /// 给TOP请求签名。
        /// 
        /// 所有字符型的TOP请求参数
        /// 签名密钥
        /// 签名方法,可选值:md5, hmac
        /// 签名
        public static string SignTopRequest(IDictionary parameters, string secret, string signMethod)
        {
            return SignTopRequest(parameters, null, secret, signMethod);
        }
        /// 
        /// 给TOP请求签名。
        /// 
        /// 所有字符型的TOP请求参数
        /// 请求主体内容
        /// 签名密钥
        /// 签名方法,可选值:md5, hmac
        /// 签名
        public static string SignTopRequest(IDictionary parameters, string body, string secret, string signMethod)
        {
            // 第一步:把字典按Key的字母顺序排序
            IDictionary sortedParams = new SortedDictionary(parameters, StringComparer.Ordinal);
            // 第二步:把所有参数名和参数值串在一起
            StringBuilder query = new StringBuilder();
            if (Constants.SIGN_METHOD_MD5.Equals(signMethod))
            {
                query.Append(secret);
            }
            foreach (KeyValuePair kv in sortedParams)
            {
                if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value))
                {
                    query.Append(kv.Key).Append(kv.Value);
                }
            }
            // 第三步:把请求主体拼接在参数后面
            if (!string.IsNullOrEmpty(body))
            {
                query.Append(body);
            }
            // 第四步:使用MD5/HMAC加密
            byte[] bytes;
            if (Constants.SIGN_METHOD_HMAC.Equals(signMethod))
            {
                HMACMD5 hmac = new HMACMD5(Encoding.UTF8.GetBytes(secret));
                bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
            }
            else if (Constants.SIGN_METHOD_HMAC_SHA256.Equals(signMethod))
            {
                HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
                bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
            }
            else
            {
                query.Append(secret);
                MD5 md5 = MD5.Create();
                bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
            }
            // 第五步:把二进制转化为大写的十六进制
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString("X2"));
            }
            return result.ToString();
        }
        /// 
        /// 清除字典中值为空的项。
        /// 
        /// 待清除的字典
        /// 清除后的字典
        public static IDictionary CleanupDictionary(IDictionary dict)
        {
            IDictionary newDict = new Dictionary(dict.Count);
            foreach (KeyValuePair kv in dict)
            {
                if (kv.Value != null)
                {
                    newDict.Add(kv.Key, kv.Value);
                }
            }
            return newDict;
        }
        /// 
        /// 把对象转换为JSON字符串。
        /// 
        public static string ObjectToJson(object obj)
        {
            return JSON.ToJSON(obj, jp);
        }
        /// 
        /// 把对象转换为JSON字符串。
        /// 
        public static string ObjectToJson(object obj, JSONParameters newjp)
        {
            return JSON.ToJSON(obj, newjp);
        }
        /// 
        /// 把JSON字符串转换为对象。
        /// 
        public static object JsonToObject(string json)
        {
            return JSON.Parse(json);
        }
        /// 
        /// 把JSON解释为API响应对象。
        /// 
        /// API响应类型
        /// JSON字符串
        /// API响应对象
        public static T ParseResponse(string json) where T : TopResponse
        {
            TopJsonParser parser = new TopJsonParser();
            return parser.Parse(json);
        }
        /// 
        /// 获取从1970年1月1日到现在的毫秒总数。
        /// 
        /// 毫秒数
        public static long GetCurrentTimeMillis()
        {
            return (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
        }
        /// 
        /// 获取本机的局域网IP。
        /// 
        public static string GetIntranetIp()
        {
            if (intranetIp == null)
            {
                NetworkInterface[] nis = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface ni in nis)
                {
                    if (OperationalStatus.Up == ni.OperationalStatus && (NetworkInterfaceType.Ethernet == ni.NetworkInterfaceType || NetworkInterfaceType.Wireless80211 == ni.NetworkInterfaceType))
                    {
                        foreach (UnicastIPAddressInformation info in ni.GetIPProperties().UnicastAddresses)
                        {
                            if (AddressFamily.InterNetwork == info.Address.AddressFamily)
                            {
                                intranetIp = info.Address.ToString();
                                break;
                            }
                        }
                        if (intranetIp != null) break;
                    }
                }
            }
            if (intranetIp == null)
            {
                intranetIp = "127.0.0.1";
            }
            return intranetIp;
        }
    }
}