using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using QMAPP.FJC.Entity.Basic;
using OpcServerHost.Init;
using QMFrameWork.Common.Serialization;
using QMAPP.FJC.Entity.QT;

namespace OpcServerHost
{
     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
     //[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class OpcService : IOpcService
    {
        
        IControlCallback callback = null;

        static object syncObj = new Object();

        /// <summary>
        /// 工控机注册服务端
        /// </summary>
        /// <param name="machineNo"></param>
        /// <returns></returns>
        public int Register(string machineNo)
        {
            int mouldnumber = 1;
            //建立双通道通信
            lock (syncObj)//线程的同步性,同步访问多个线程的任何变量,利用lock(独占锁),确保数据访问的唯一性。
            {
                if (ChatEventHelper.chatters.ContainsKey(machineNo) == false)
                {
                    //添加客户信息
                    ChatEventHelper.chatters.Add(machineNo, ReturnProductCode);

                    //添加客户端时间标记
                    //ChatEventHelper.chatterTimes.Add(machineNo, System.DateTime.Now);
                    Console.WriteLine(machineNo + ":Register");

                }
                else
                {
                    //如果包含了客户端信息,先删除客户端信息
                    ChatEventHelper.chatters.Remove(machineNo);
                    //ChatEventHelper.chatterTimes.Remove(machineNo);

                    //删除后再次添加
                    ChatEventHelper.chatters.Add(machineNo, ReturnProductCode);
                    //删除后再次添加客户端时间标记
                    //ChatEventHelper.chatterTimes.Add(machineNo, System.DateTime.Now);

                    Console.WriteLine(machineNo + ":Register");
                }

                //获取设备模架号
                #region 

                mouldnumber = ParaInit.GetMoulderOfMachine(machineNo);

                #endregion

                callback = OperationContext.Current.GetCallbackChannel<IControlCallback>();
            }

            return mouldnumber;
        }
        
        /// <summary>
        /// 退出登录
        /// </summary>
        /// <param name="machineNo"></param>
        /// <returns></returns>
        public int Logout(string machineNo)
        {

            if (ChatEventHelper.chatters.ContainsKey(machineNo))
            {
                lock (syncObj)
                {
                    //删除客户端
                    ChatEventHelper.chatters.Remove(machineNo);
                }
            }

            return 1;
            
        }

        /// <summary>
        /// 向向设备发送可操作标记
        /// </summary>
        /// <param name="order"></param>
        public void SendOperateOrder(string paraStr)
        {
            try
            {

                if (paraStr.StartsWith("HeartBeat"))//接收到心跳请求
                {
                    string machinecode=paraStr.Split(':')[1];
                    Console.WriteLine(paraStr);
                    ReturnProductCodeToMachine(new ChatEventArgs { MachineCode = machinecode, MessageContent = "", MessageType = "HeartBeat" });
                }
                else
                {

                    DAI config = new DAI();

                    config = JsonConvertHelper.GetDeserialize<DAI>(paraStr);

                    Console.WriteLine("WORKLOC_CODE:" + config.WORKLOC_CODE
                        + " DA_CODE:" + config.DA_CODE + " Result:" + config.Result.ToString() + " MOULD_CODE:" + config.MOULD_CODE);

                    ParaInit.SendSignal(config);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            

        }

        public void SendCompleteOrder(string machinecode)
        {
            Console.WriteLine(machinecode);

        }

        /// <summary>
        /// 更新客户端连接服务器
        /// </summary>
        /// <param name="machineNo"></param>
        /// <returns></returns>
        public int UpdateClientInfo(string machineNo)
        {
            //建立双通道通信
            //线程的同步性,同步访问多个线程的任何变量,利用lock(独占锁),确保数据访问的唯一性。
            lock (syncObj)
            {
                if (ChatEventHelper.chatters.ContainsKey(machineNo))
                {
                    ChatEventHelper.chatters.Remove(machineNo);
                    ChatEventHelper.chatterTimes.Remove(machineNo);
                }

                ChatEventHelper.chatters.Add(machineNo, ReturnProductCode);
                ChatEventHelper.chatterTimes.Add(machineNo,System.DateTime.Now);

                callback = OperationContext.Current.GetCallbackChannel<IControlCallback>();
            }

            return 1;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReturnProductCode(object sender, ChatEventArgs e)
        {

            ReturnMessage obj = new ReturnMessage();
            obj.MessageContent = e.MessageContent;
            obj.MessageType = e.MessageType;

            callback.ReturnResult(e.MessageType, e.MessageContent);
        }

        public void ReturnProductCodeToMachine(ChatEventArgs e)
        {
            try
            {
                //初始化传送参数
                ChatEventHelper.ChatEventHandler chatEvent;

                lock (syncObj)
                {
                    //通过工控机名称获取事件信息
                    chatEvent = ChatEventHelper.chatters[e.MachineCode];
                    //查找成员字典中,找到要接收者的委托调用
                }

                //向工控机发送条码信息
                chatEvent.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);//异步方式调用接收者的委托调用
            
            }
            catch (KeyNotFoundException ex)
            {

            }

        }

        private void EndAsync(IAsyncResult ar)
        {
            ChatEventHelper.ChatEventHandler d = null;

            try
            {
                //封装异步委托上的异步操作结果
                System.Runtime.Remoting.Messaging.AsyncResult asres = (System.Runtime.Remoting.Messaging.AsyncResult)ar;
                d = ((ChatEventHelper.ChatEventHandler)asres.AsyncDelegate);
                d.EndInvoke(ar);
            }
            catch
            {
                //ChatEvent -= d;
            }
        }

    }
}