using BPA.Utility;
using HBLConsole.Communication;
using System;
using System.Collections.Generic;
using System.Threading;
using static HBLDevice.IceCream.MessageDefine;
using HBLConsole.Service;
using HBLConsole.Model;

namespace HBLDevice.IceCream
{
    public class IceCreamMachine
    {
        //指令组装
        private CommandHandler commandHandler = new CommandHandler();
        //通讯代理
        SerialPortClient commProxy = null;
        //数据仓库
        private DataStorage<byte> dataStorage = new DataStorage<byte>();
        //主线程运行标识
        private bool running = false;
        //是否下发指令，主线程等待
        private bool free = true;
        public Action<string> SendCallback;
        public Action<string> ReciveCallback;



        public IceCreamMachine(string portName, BaudRates baud)
        {
            commProxy = new SerialPortClient(portName, baud);
            commProxy.SetDataStorage(dataStorage);
            commandHandler.Init(commProxy);
            commandHandler.PauseAsk = delegate (bool pause)
            {
                free = !pause;
            };
        }

        public void Start()
        {
            commProxy.Start();
            running = true;
            MainLoop();
        }

        public void Stop()
        {
        }

        private MSG_RESOLVE_STEP currentStep;
        private void MainLoop()
        {
            ThreadOperate.GetInstance.StartLong(new Action(() =>
            {
                if (free)
                {
                    commProxy.SendData(commandHandler.GetHeartDW());
                    SendCallback?.Invoke(BitConverter.ToString(commandHandler.GetHeartDW()));
                }
                Thread.Sleep(500);
            }), "冰淇淋询问线程");

            ThreadOperate.GetInstance.StartLong(new Action(() =>
            {
                ResolveMsg();
                //Thread.Sleep(2000);
            }), "冰淇淋解析线程");

            //Executer.GetInstance().Start(() =>
            //{
            //    while (running)
            //    {
            //        commProxy.SendData(commandHandler.GetHeartDW());
            //        SendCallback?.Invoke(BitConverter.ToString(commandHandler.GetHeartDW()));
            //        Thread.Sleep(2000);
            //    }
            //}, "冰淇淋询问线程");

            //Executer.GetInstance().Start(() =>
            //{
            //    ResolveMsg();
            //}, "冰淇淋解析线程");
        }
        int contentLength = 0;
        int currentContentOffset = 0;
        private void ResolveMsg()
        {

            //while (running)
            //{
            List<byte> temp = new List<byte>();
            //一系列解包
            while (dataStorage.GetSize() > 0)
            {
                byte item = dataStorage.GetData();
                switch (currentStep)
                {
                    case MSG_RESOLVE_STEP.NONE:
                        if (item == MessageDefine.HEADER1)
                        {
                            temp.Add(item);
                            currentStep = MSG_RESOLVE_STEP.HEADER1;
                            continue;
                        }
                        break;
                    case MSG_RESOLVE_STEP.HEADER1:
                        if (item == MessageDefine.HEADER2_UP)
                        {
                            temp.Add(item);
                            currentStep = MSG_RESOLVE_STEP.HEADER2;
                            continue;
                        }
                        else
                        {
                            temp.Clear();
                            currentStep = MSG_RESOLVE_STEP.NONE;
                            continue;
                        }
                    case MSG_RESOLVE_STEP.HEADER2:
                        switch ((IC_CMD)item)
                        {
                            case IC_CMD.HEART:
                                temp.Add(item);
                                contentLength = MessageDefine.MSG_LENGTH[(IC_CMD)item];
                                currentContentOffset = 0;
                                currentStep = MSG_RESOLVE_STEP.CMD;
                                break;
                            default:
                                temp.Clear();
                                currentStep = MSG_RESOLVE_STEP.NONE;
                                break;
                        }
                        break;
                }
                int retry = 3;
                while (dataStorage.GetSize() < contentLength + 2 && retry >= 0)
                {
                    retry--;
                    Thread.Sleep(100);
                }
                if (retry < 0)
                {
                    currentStep = MSG_RESOLVE_STEP.NONE;
                    currentContentOffset = 0;
                    contentLength = 0;
                    continue;
                }
                while (currentContentOffset < contentLength)
                {
                    item = dataStorage.GetData();
                    temp.Add(item);
                    currentContentOffset++;
                }

                retry = 3;
                while (dataStorage.GetSize() < 2 && retry >= 0)
                {
                    retry--;
                    Thread.Sleep(100);
                }
                temp.Add(dataStorage.GetData());
                temp.Add(dataStorage.GetData());
                ReciveCallback?.Invoke(BitConverter.ToString(temp.ToArray()));
                MorkIStatus.GetInstance().ProcessMsg(temp.ToArray());
                currentStep = MSG_RESOLVE_STEP.NONE;
                continue;
            }
            Thread.Sleep(5);
            //}
        }
    }

}
