using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using parkMonitor.DB;
using parkMonitor.LOG;
using parkMonitor.entity;
using parkMonitor.model;
using System.Configuration;
using System.Threading;
using parkMonitor.server.uiLogServer;
using parkMonitor.DBLocation;

namespace parkMonitor.server.CoreThread
{
    class CoreThreadTest2 : IEquipments, ICoreThreadDoWorking
    {

        int equipmentStatus_address;//设备总控状态地址
        //获取PLC句柄
        IEquipments PLC;
        //获取队列句柄
        IEquipments queuingThread;
        //获取号牌句柄
        IEquipments NumMachine;
        //
        DBLocationOperator locationOper;
        DBOperation oper;
        int localGarageId = 0;

        string[] equipNames = new string[] { EquipmentName.PLC, EquipmentName.NumMachine, EquipmentName.Web, EquipmentName.Queue };

        public CoreThreadTest2()
        {
            try
            {
                equipmentStatus_address = Convert.ToInt32(ConfigurationManager.AppSettings["equipmentStatus_address"]);
                localGarageId = Convert.ToInt32(ConfigurationManager.AppSettings["localGarageId"]);
                locationOper = new DBLocationOperator();
                oper = new DBOperation();
            }
            catch (Exception) { }
        }

        public void Start()
        {

            for (int i = 0; i < equipNames.Length; ++i)
            {
                IEquipments equip = EquipmentSimpleFactory.ins.CreateEquipment(equipNames[i]);
                if (equip != null)
                {
                    equip.Start();
                }
            }
            PLC = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.PLC);
            queuingThread = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.Queue);
            NumMachine = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.NumMachine);
            //BeginWorking();
            //监听总状态改变消息
            //由监控线程发出
            AsyncCmdServer.ins.listen(AsyncCmdType.TotalStatusChanged, (AlarmStatus type) =>
            {
                if (type != AlarmStatus.Normal)
                {
                    hangUp();
                }
            });
        }

        public AbstractMessage GetMessage()
        {
            return null;
        }

        public void SetMessage(AbstractMessage message)
        {

        }

        public void Stop()
        {
            for (int i = 0; i < equipNames.Length; ++i)
            {
                IEquipments equip = EquipmentSimpleFactory.ins.FindEquipment(equipNames[i]);
                if (equip != null)
                {
                    equip.Stop();
                }
            }
            AbstractCmd.isClosing = true;//停止运行中指令
        }

        public void BeginWorking()
        {
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Func<AbstractMessage> func = new Func<AbstractMessage>(GetExecuteNumberPlate);

                    TaskFactory taskFactory = new TaskFactory();
                    List<Task> tasklist = new List<Task>();
                    IAsyncResult result = func.BeginInvoke(null, null);
                    Action act1 = new Action(() =>
                    {
                        GetTotalStatus();
                    });
                    tasklist.Add(taskFactory.StartNew(act1));
                    Task.WaitAll(tasklist.ToArray());
                    Command queueCmd = (Command)func.EndInvoke(result);
                    Task.Factory.StartNew(() =>
                    {
                        SimpleCMDFactory simpleCMDFactory = new SimpleCMDFactory();
                        AbstractCmd abstractCmd = simpleCMDFactory.createCmd(queueCmd);
                        abstractCmd.executeCmd(queueCmd);
                    });
                    Thread.Sleep(100);
                }
            });

            //同步数据库
            //Task.Factory.StartNew(() =>
            //{
            //    while (true)
            //    {
            //        try
            //        {
            //            //更新车库表车位数
            //            int freeSpaceCount = locationOper.getGarageFreeSpace(localGarageId);
            //            oper.UpdateGarageFreeSpace(freeSpaceCount, localGarageId);
            //            //更新车位状态                       
            //            int[] parkingSpace = locationOper.GetAllParkingSpaceID(localGarageId);
            //            if (parkingSpace != null)
            //            {
            //                //两种解决方法：
            //                //1.加配置文件，每个车库的起始车位ID
            //                //2.Dictionary<>
            //                for (int i = 0; i < parkingSpace.Length; i++)
            //                {
            //                    oper.UpdateParkingSpaceState(i, parkingSpace[i]);
            //                }
            //            }
            //        }
            //        catch (Exception)
            //        {
            //            Console.WriteLine("无同步数据");
            //        }
            //        Thread.Sleep(8000);
            //    }
            //});
        }

        /// <summary>挂起</summary>
        public void hangUp()
        {

        }
        /// <summary>
        /// 获取PLC总控状态
        /// </summary>
        private void GetTotalStatus()
        {
            PLCMessage PLCMsg = null;
            int normalStatus = 0;
            while (true)
            {
                PLCMsg = (PLCMessage)PLC.GetMessage();
                if (PLCMsg != null && PLCMsg.originalPlcList != null && PLCMsg.originalPlcList.Count != 0)
                {
                    normalStatus = Convert.ToInt32(PLCMsg.originalPlcList[equipmentStatus_address].Value);
                }
                //设备总控状态
                if (normalStatus == 1)
                {
                    UILogServer.ins.log("设备总状态正常");
                    break;
                }
                Thread.Sleep(100);
            }
        }
        /// <summary>
        /// 获取可执行号牌
        /// </summary>
        private AbstractMessage GetExecuteNumberPlate()
        {
            AbstractMessage msg = null;
            while (true)
            {
                msg = queuingThread.GetMessage();
                if (msg != null)
                {
                    break;
                }
            }
            return msg;
        }
    }
}
