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

namespace BL.Utility.Matrix.UdpInteraction
{
    class DataGram
    {
        private static int pkgLength = 250; //包长度
        /// <summary>
        /// 数据报缓存
        /// </summary>
        private static Dictionary<string, PackObject> grams = new Dictionary<string, PackObject>();
        private static FormMainUdpClient form;

        /// <summary>
        /// 设置主窗体
        /// </summary>
        /// <param name="form"></param>
        public static void SetHost(FormMainUdpClient form)
        {
            DataGram.form = form;
        }

        /// <summary>
        /// 接收：解析数据报，组包
        /// 注意一个问题：多个数据报间是异步的，不一定头包先到
        /// 接收的数据格式有两种：
        /// 1、[wm]data
        /// 2、[wm:{msgKey}:{packs}:{i}]
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string Pack(string message)
        {
            //抛弃非本系统数据
            if (!message.StartsWith("[wm")) return null;

            //解析
            if (message.StartsWith("[wm]"))
            {
                //单包
                return message.Substring(4);
            }
            else
            {
                //组包
                int gramEndIndex = message.IndexOf(']');
                string gram = message.Substring(1, gramEndIndex - 1);
                string[] gramArr = gram.Split(':');
                string msgKey = gramArr[1];
                int count = int.Parse(gramArr[2]);
                int index = int.Parse(gramArr[3]);
                string data = message.Substring(gramEndIndex + 1);

                PackObject packObj;
                bool found = grams.TryGetValue(msgKey, out packObj);
                if (!found)
                {
                    packObj = new PackObject()
                    {
                        Count = count,
                        Indexes = new Dictionary<int, string>()
                    };
                    packObj.Indexes.Add(index, data);
                    grams.Add(msgKey, packObj);
                    form.BeginInvoke(new Action(() =>
                    {
                        form.addMsg(string.Format("接收到 {0} 的数据片段: {1}", packObj.Count, index));
                    }));
                }
                else
                {
                    bool exists = packObj.Indexes.ContainsKey(index);
                    if (!exists)
                    {
                        packObj.Indexes.Add(index, data);
                        form.BeginInvoke(new Action(() =>
                        {
                            form.addMsg(string.Format("接收到 {0} 的数据片段: {1}", packObj.Count, index));
                        }));
                    }

                    //组包
                    if (packObj.Indexes.Count == packObj.Count)
                    {
                        string json = string.Empty;
                        var dictSorted = packObj.Indexes.OrderBy(c => c.Key).ToDictionary(o => o.Key, p => p.Value);
                        foreach (var item in dictSorted)
                        {
                            json += item.Value;
                        }
                        grams.Remove(msgKey);   //释放缓存
                        return json;
                    }
                }
            }

            return null;
        }
    }

    /// <summary>
    /// 包对象
    /// </summary>
    class PackObject
    {
        /// <summary>
        /// 总包数
        /// </summary>
        public int Count { get; set; }
        /// <summary>
        /// 接收到包索引
        /// </summary>
        public Dictionary<int, string> Indexes { get; set; }
    }
}
