using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ChuPiao.Common.Utils;
using ChuPiao.Common.Core.Security;

namespace ChuPiao.Common.Communication.GtdJson
{
    /// <summary>
    /// 消息包基类
    /// </summary>
    public abstract class PackRetBase
    {
        /// <summary>
        /// 解包
        /// </summary>
        /// <param name="strpack"></param>
        public void UnPack(string strpack)
        {
            JObject jo = (JObject)JsonConvert.DeserializeObject(strpack);
            JToken head = jo["head"];
            AgentId = head["agentId"].ToString();
            MessageId = head["msgId"].ToString();
            Timestamp = head["timestamp"].ToString();
            string sign = head["sign"].ToString();
            JToken body = jo["body"];

            //body.ToString();    //{\r\n  \"message\": \"无票可取\",\r\n  \"status\": \"301\"\r\n}      按body去解析的时候，会自带格式，所以不用这种方式去取body的字符串

            //解析前验签，验不过就不用解析了，看来有点行不通，估计要先解析再
            int index_start = strpack.IndexOf("\"body\":"); body.ToString();
            int index_end = strpack.IndexOf("}}", index_start);
            string bodystr = strpack.Substring(index_start + 7, index_end - index_start - 7 + 1);   //{"lotId":911}
            Logger.Log.Debug(string.Format("{0} 返回<--{1}", AgentId, bodystr));

            bodystr = bodystr.Replace(" ", "#*#*#");   //空格转码前后有区别，所以前后替换一下，以后碰到其它的再说，没办法，服务端的是unicode送进MD5的，跟他们的来吧，不纠结
            bodystr = GetUnicode(bodystr);
            bodystr = bodystr.Replace("#*#*#", " ");

            string enstr = string.Format("{0}{1}{2}{3}{4}", MessageId, AgentId, Timestamp, Salt, bodystr);   //没办法，服务端的是unicode送进MD5的，跟他们的来吧，不纠结
            string tosign = MD5Util.Encrypt(enstr, Encoding.GetEncoding("utf-8"));
            if (sign != tosign)
            {
                throw new Exception("解包错误，包校验失败-" + enstr);

            }
            UnPackBody(body);
        }

        protected string GetUnicode(string text)
        {
            string result = "";
            for (int i = 0; i < text.Length; i++)
            {
                if ((int)text[i] > 32 && (int)text[i] < 127)
                {
                    result += text[i].ToString();
                }
                else
                    result += string.Format("\\u{0:x4}", (int)text[i]);
            }
            return result;
        }

        /// <summary>
        /// 包体解包
        /// </summary>
        /// <param name="body"></param>
        public abstract void UnPackBody(JToken body);


        #region 属性

        /// <summary>
        /// 站点编号
        /// </summary>
        public string AgentId
        {
            get { return _agentId; }
            set { _agentId = value; }
        }

        ///<summary>
        ///密钥
        ///</summary>
        public string Salt
        {
            get { return _salt; }
            set { _salt = value; }
        }
        /// <summary>
        /// 消息ID
        /// </summary>
        public string MessageId
        {
            get { return _messageId; }
            set { _messageId = value; }
        }
        /// <summary>
        /// 时间戳
        /// </summary>
        public string Timestamp
        {
            get { return _timestamp; }
            set { _timestamp = value; }
        }

        private string _salt = "";
        private string _messageId = "";
        private string _timestamp = "";
        private string _agentId = "";
        #endregion
    }
}
