using ProjectBase.Data.Logs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIASUN.Autopilot.Device
{
    #region 事件链
    public class EventManage
    {
        static EventManage _instance;
        public static EventManage Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new EventManage();
                    _instance.EventBuffer = new Dictionary<string, List<object>>();
                }
                return _instance;
            }
        }

        /// <summary>
        /// 对于分包数据，在此根据事件名称缓存包的消息体数据
        /// </summary>
        public Dictionary<string, List<object>> EventBuffer { get; private set; }

        /// <summary>
        /// 跟踪所有事件的注册和订阅
        /// </summary>
        private Hashtable delegateMap = new Hashtable();

        /// <summary>
        /// 订阅事件添加到客户端的委托。
        /// </summary>
        /// <param name="eventName">事件名称。</param>
        /// <param name="handler">客户端的委托句柄。</param>
        public void SubscribeEvent(string eventName, EventProcessingHandler handler)
        {
            // 确保同一时间只有一个线程来修改委托链。
            lock (this)
            {
                // 检查委托链是否为null。
                // 如果为null，则添加客户端委托作为初始句柄，
                // 否则，添加委托到链表中。
                if (!delegateMap.ContainsKey(eventName))
                {
                    delegateMap.Add(eventName, handler);
                }
                else
                {
                    Delegate delegateChain = (Delegate)delegateMap[eventName];
                    // 添加委托到链表中
                    delegateChain = Delegate.Combine(delegateChain, handler);
                    // 在Hashtable中重置委托链
                    delegateMap[eventName] = delegateChain;
                }
            }
        }

        /// <summary>
        /// 取消事件订阅，从委托链中移除客户端的委托
        /// </summary>
        /// <param name="eventName">事件名称</param>
        /// <param name="handler"></param>
        public void UnSubscribeEvent(string eventName, EventProcessingHandler handler)
        {
            // 确保同一时间只有一个线程来修改委托链。
            lock (this)
            {
                Delegate delegateChain = (Delegate)delegateMap[eventName];
                // 检查委托链是否为null。
                // 如果不为null，则从委托链中移除。
                if (delegateChain != null)
                {
                    // 移除
                    delegateChain = Delegate.Remove(delegateChain, handler);
                    if (delegateChain == null)
                    {
                        delegateMap.Remove(eventName);
                    }
                    else
                    {
                        // 在Hashtable中重置委托链
                        delegateMap[eventName] = delegateChain;
                    }
                }
            }
        }

        /// <summary>
        /// 提出事件调用指定事件的委托链。
        /// </summary>
        /// <param name="eventName">事件名称。</param>
        /// <param name="content">通知的内容。</param>
        public void RaiseEvent(string eventName, IList<object> content)
        {
            Delegate delegateChain = (Delegate)delegateMap[eventName];

            if (delegateChain == null)
            {
                string msg = string.Format("没有找到消息{0}的订阅事件", eventName);
                LogHelper.log.Error(msg);
                return;
            }


            delegateChain.DynamicInvoke(new PackageProcessingEventArgs(content));
            return;



            // 找回链表中的委托。
            IEnumerator invocationEnumerator = delegateChain.GetInvocationList().GetEnumerator();
            // 遍历查找并调用。
            while (invocationEnumerator.MoveNext())
            {
                Delegate handler = (Delegate)invocationEnumerator.Current;
                try
                {
                    handler.DynamicInvoke(new object[] { eventName, content });
                }
                catch (Exception ex)
                {
                    string msg = string.Format("遍历查找事件{0}时出现错误:{1}。", eventName, ex.Message);
                    LogHelper.log.Error(msg);
                    // 如果接收事件通知的客户端不存在，则移除此委托。
                    //delegateChain = Delegate.Remove(delegateChain, handler);
                    //delegateMap[eventName] = delegateChain;
                }
            }
        }
    }
    #endregion 事件链

    #region eventargs
    /// <summary>
    /// 接收到数据后，将包数据传递给调用者
    /// </summary>
    /// <param name="packageBytes"></param>
    public delegate void EventProcessingHandler(PackageProcessingEventArgs e);
    public class PackageProcessingEventArgs : EventArgs
    {
        public IList<object> PackageBytes { get; set; }
        public PackageProcessingEventArgs(IList<object> packageBytes)
        {
            this.PackageBytes = packageBytes;
        }
    }

    /// <summary>
    /// 接收到数据拆包后，将消息通知给调用者
    /// </summary>
    /// <param name="message"></param>
    public delegate void ReceiveMessageEventHandler(ReceiveMessageEventArgs e);
    public class ReceiveMessageEventArgs : EventArgs
    {
        public object Message { get; set; }
        public ReceiveMessageEventArgs(object message)
        {
            this.Message = message;
        }
    }

    #endregion 
}
