using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.VpwCell;
using PunkHPX8_RT.Devices.VpwMain;
using PunkHPX8_RT.Modules.VpwCell;
using SecsGem.Core.ItemModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwMain
{
    public class VPWHomeRoutine : RoutineBase, IRoutine
    {
        private enum HomeStep
        {
            CloseDegasPumpAndAdjustValve,
            ChameberUp,
            OpenCellDrainValve,
            HomeRotation,
            CheckRotationStatus,
            StartRotation,
            CheckRotationRunning,
            CloseDiwDegas,
            N2PurgeDelay,
            CloseN2Purge,
            BoostPumpEnable,
            CheckPumpEnable,
            FlowDelay,
            CheckFlow,
            CheckCellFlow,
            StopRotation,
            CheckStopStatus,
            CheckTotalFlowOk,
            LastHomeRotation,
            CheckLastHomeRotation,
            CheckFlowOk,
            DegasDelay,
            OpenDegas,
            ChamberDown,
            LastCheckStatus,
            End
        }
        #region 常量 
        /// 
        /// 增加额外一分钟
        /// 
        private const int PLUS_TIME = 60000;
        #endregion
        #region 内部变量
        /// 
        /// Cell device集合
        /// 
        private List _vpwCellDevices=new List();
        /// 
        /// Main Device
        /// 
        private VpwMainDevice _mainDevice;
        /// 
        /// cell集合
        /// 
        private List _cellLst=new List();
        /// 
        /// N2 Purge时长
        /// 
        private int _n2PurgeTime = 15000;
        /// 
        /// Flow holder off time
        /// 
        private int _flowFaultHolderoffTime = 15000;
        /// 
        /// Degas delay时间
        /// 
        private int _degasEnableDelayTime = 2000;
        /// 
        /// 旋转速度
        /// 
        private int _rotationSpeed = 0;
        /// 
        /// 总流量起始流量数值
        /// 
        private double _totalFlowStartLimit = 2.0;
        /// 
        /// Cell起始流量数值
        /// 
        private double _cellFlowStartLimit = 2.0;
        /// 
        /// total flow合格
        /// 
        private bool _totalFlowOk = false;
        /// 
        /// cell flow合格集合
        /// 
        private Dictionary _cellFlowOk = new Dictionary();
        /// 
        /// 检验流量是否ok
        /// 
        private bool _checkFlowOk = false;
        /// 
        /// 总流量
        /// 
        private double _totalFlow = 0;
        /// 
        /// Cell注意集合
        /// 
        private Dictionary _cellFlows = new Dictionary();
        /// 
        /// 检验chamber是否上升/下降到位
        /// 
        private int _checkChamberUpDownTimes = 3;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        public VPWHomeRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(HomeStep.CloseDegasPumpAndAdjustValve, CloseDegasPumpAndAdjustValve, _delay_1ms)
                .Run(HomeStep.ChameberUp, _mainDevice.ChamberUp, CheckChamberClosed, _checkChamberUpDownTimes*1000)
                .Run(HomeStep.OpenCellDrainValve, OpenCellDrainValve, CheckCellDrainValveStatus, _delay_2s)
                .Run(HomeStep.HomeRotation,HomeAllRotation,_delay_1ms)
                .WaitWithStopCondition(HomeStep.CheckRotationStatus,CheckAllRotationHomeStatus,CheckAllRotationHomeStopStatus)
                .Run(HomeStep.StartRotation,StartRotation,_delay_1ms)
                .Wait(HomeStep.CheckRotationRunning,CheckRotationRunningStatus,500)
                .Run(HomeStep.CloseDiwDegas,CloseDiwDegas)
                .Delay(HomeStep.N2PurgeDelay,_n2PurgeTime)
                .Run(HomeStep.CloseN2Purge,_mainDevice.N2PurgeValveOff,_delay_1ms)
                .Run(HomeStep.BoostPumpEnable,OpenBoostPump,_delay_1ms)
                .Wait(HomeStep.CheckPumpEnable, () => { return _mainDevice.CommonData.BoosterPumpStatus; },_delay_1s)
                .Delay(HomeStep.FlowDelay,_flowFaultHolderoffTime)
                .Run(HomeStep.CheckFlow,CheckTotalFlow,_delay_1ms)
                .Run(HomeStep.CheckCellFlow,CheckCellFlow,_delay_1ms)
                .Run(HomeStep.StopRotation,StopRotationAxis,_delay_1ms)
                .WaitWithStopCondition(HomeStep.CheckRotationStatus,CheckStopPostionEndStatus,CheckStopPostionStopStatus)
                .RunIf(HomeStep.CheckTotalFlowOk, !_totalFlowOk, CheckTotalFlowFailedAction, _delay_1ms)
                .Run(HomeStep.LastHomeRotation,HomeAllRotation,_delay_1ms)
                .WaitWithStopCondition(HomeStep.CheckLastHomeRotation, CheckAllRotationHomeStatus, CheckAllRotationHomeStopStatus)
                .Run(HomeStep.CheckFlowOk,CheckFlowOk,_delay_1ms)
                .DelayIf(HomeStep.DegasDelay,_checkFlowOk,_degasEnableDelayTime)
                .RunIf(HomeStep.OpenDegas,_checkFlowOk,OpenDegasPump,_delay_1ms)
                .RunIf(HomeStep.ChamberDown,_checkFlowOk, () => { return _mainDevice.ChamberDown(); }, 
                    () => { return !_mainDevice.CommonData.ChamberClosed && _mainDevice.CommonData.ChamberOpened; })
                .Run(HomeStep.LastCheckStatus,LastCheckResult,_delay_1ms)
                .End(HomeStep.End,NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 关闭degaspump和degas adjust valve
        /// 
        /// 
        private bool CloseDegasPumpAndAdjustValve()
        {
            return _mainDevice.DegasAdjustOff() && _mainDevice.DegasPumpDisable();
        }
        /// 
        /// 关闭所有的泵和阀 并返回false
        /// 
        /// 
        private bool CheckTotalFlowFailedAction()
        {
            LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $" current total flow {_mainDevice.CommonData.DiwTotalFlow} is less than {_totalFlowStartLimit}");
            _mainDevice.BoosterPumpDisable() ;
            _mainDevice.DiwDisable() ;
            _mainDevice.DiwProcessOff() ;
            _mainDevice.DiwDegasValveOff();
            foreach (var item in _cellLst)
            {
                 item.FlowDripOff();
                 item.FlowSmallOff() ;
                 item.FlowLargeOff();
            }
            return false;
        }
        /// 
        /// 检验Chamber关闭
        /// 
        /// 
        private bool CheckChamberClosed()
        {
            return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
        }
        /// 
        /// 打开所有cell valve
        /// 
        /// 
        private bool OpenCellDrainValve()
        {
            foreach(var device in _cellLst)
            {               
                bool result= device.DrainValveOn();
                if (!result)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} open drain valve failed");
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 检验Cell Drain状态
        /// 
        /// 
        private bool CheckCellDrainValveStatus()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.CommonData.DrainValve;
                if (!result)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{item.Module} drain valve is not opened");
                    return false;
                }
            }
            return true;
        }
        /// 
        /// Home All Rotation
        /// 
        /// 
        private bool HomeAllRotation()
        {
            foreach(var item in _cellLst)
            {
                bool result = item.HomeRotation();
                if (!result)
                {
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 检验所有Rotation Home成功
        /// 
        /// 
        private bool CheckAllRotationHomeStatus()
        {
            int count = 0;
            foreach (var item in _cellLst)
            {
                bool result = item.CheckHomeEndStatus();
                if (result)
                {
                    count++;
                }
            }
            bool success= count == _cellLst.Count ;
            if (success)
            {                
                foreach(var item in _cellLst)
                {
                    item.SetRotationSpeed(_rotationSpeed);
                }
            }
            return success;
        }
        /// 
        /// rotation电机 home是否停止
        /// 
        /// 
        private bool CheckAllRotationHomeStopStatus()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.CheckRotationStopStatus();
                if (result)
                {
                    return true;
                }
            }
            return false;
        }
        /// 
        /// 启动rotation
        /// 
        /// 
        private bool StartRotation()
        {
            int totalTime =(_n2PurgeTime + _flowFaultHolderoffTime + PLUS_TIME)/1000;
            int targetPsition = _rotationSpeed * totalTime;
            foreach (var item in _cellLst)
            {
                bool result = item.RotationProfilePosition(targetPsition);
                if (!result)
                {
                    StopAllRotation();
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 检验Rotation是否运动
        /// 
        /// 
        private bool CheckRotationRunningStatus()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.CheckRotationRunning();
                if (!result)
                {
                    StopAllRotation();
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 停止所有rotation电机
        /// 
        private void StopAllRotation()
        {
            foreach (var item in _cellLst)
            {
                item.StopProfilePosition();
            }
        }
        /// 
        /// 关闭DiwDegas等
        /// 
        /// 
        private bool CloseDiwDegas()
        {
            int count = 0;
            count+=_mainDevice.DiwDegasValveOff()?1:0;
            count+=_mainDevice.BoosterPumpDisable()?1:0;
            count+=_mainDevice.N2PurgeValveOn()?1:0;
            foreach(var item in _cellLst)
            {
                count += item.FlowDripOff()?1:0;
                count += item.FlowSmallOff() ? 1 : 0;
                count += item.FlowLargeOff() ? 1 : 0;
            }
            
            return count==_cellLst.Count*3+3;
        }
        /// 
        /// 打开Boost Pump
        /// 
        /// 
        private bool OpenBoostPump()
        {
            int count = 0;
            count += _mainDevice.BoosterPumpEnable()?1:0;
            count += _mainDevice.DiwEnable() ? 1 : 0;
            count += _mainDevice.DiwProcessOn() ? 1 : 0;
            count += _mainDevice.DiwDegasValveOn() ? 1 : 0;
            foreach (var item in _cellLst)
            {
                count += item.FlowDripOn() ? 1 : 0;
                count += item.FlowSmallOn() ? 1 : 0;
                count += item.FlowLargeOn() ? 1 : 0;
            }
            return count == _cellLst.Count*3+4;
        }
        /// 
        /// 检验流量
        /// 
        /// 
        private bool CheckTotalFlow()
        {
            double totalFlow = _mainDevice.CommonData.DiwTotalFlow;
            if (totalFlow < _totalFlowStartLimit)
            {
                _totalFlowOk = false;
            }
            else
            {
                _totalFlowOk = true;
            }
            _totalFlow = totalFlow;
            return true;
        }
        /// 
        /// 检验CellFlow
        /// 
        /// 
        private bool CheckCellFlow()
        {
            foreach (var item in _cellLst)
            {
                double cellFlow = item.CommonData.DiwFlow;
                if (cellFlow < _cellFlowStartLimit)
                {
                    _cellFlowOk[item.Module] = false;
                }
                else
                {
                    _cellFlowOk[item.Module] = true;
                    item.FlowSmallOff();
                    item.FlowLargeOff();
                }
                _cellFlows[item.Module] = cellFlow;
            }
            return true;
        }
        /// 
        /// 停止rotation
        /// 
        /// 
        public bool StopRotationAxis()
        {
            foreach(var item in _cellLst)
            {
                bool result = item.StopProfilePosition();
                if (!result)
                {             
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 检验停止是否完成
        /// 
        /// 
        public bool CheckStopPostionEndStatus()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.CheckRotationEndStatus();
                if (!result)
                {
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 检验停止失败状态
        /// 
        /// 
        public bool CheckStopPostionStopStatus()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.CheckRotationStopStatus();
                if (result)
                {
                    return true;
                }
            }
            return false;
        }
        /// 
        /// 检验流量是否ok
        /// 
        /// 
        private bool CheckFlowOk()
        {
            if (!_totalFlowOk)
            {
                _checkFlowOk = false;
                return true;
            }
            // cell flow 有问题继续做
            //foreach(var item in _cellLst)
            //{
            //    if (!_cellFlowOk[item.Module])
            //    {
            //        _checkFlowOk = false;
            //        return true;
            //    }
            //}
            _checkFlowOk = true;
            return true;
        }
        /// 
        /// 打开Degas Pump和Adjust
        /// 
        /// 
        private bool OpenDegasPump()
        {
            int count = 0;
            count+=_mainDevice.DegasPumpEnable()?1:0;
            count+=_mainDevice.DegasAdjustOn()?1:0;
            return count == 2;
        }
        /// 
        /// 最后确认结果
        /// 
        /// 
        private bool LastCheckResult()
        {
            //当前是Main Home
            if (Module == ModuleName.VPWMain1.ToString())
            {
                AllCellPostMsg();
                if (_totalFlowOk)
                {
                    return true;
                }
                else
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
                    return false;
                }
            }
            else
            {
                AllCellPostMsg();
                VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule(ModuleName.VPWMain1.ToString());
                if (_totalFlowOk)
                {
                    vpwMainEntity.CheckToPostMessage(eEvent.INFO_VPWMAIN, ModuleName.VPWMain1.ToString(), (int)VPWCellMsg.EnterIdle);
                }
                else
                {
                    vpwMainEntity.PostMsg((int)VPWMainMsg.Error);
                    LOG.WriteLog(eEvent.ERR_VPWMAIN,ModuleName.VPWMain1.ToString(), $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
                }
                if (_cellFlowOk[Module])
                {
                    return true;
                }
                else
                {
                    LOG.WriteLog(eEvent.WARN_VPW, Module, $"cell flow {_cellFlows[Module]} is less than {_cellFlowStartLimit}");
                    return false;
                }
            }
        }
        /// 
        /// 所有cell推送消息
        /// 
        private void AllCellPostMsg()
        {
            foreach (var item in _cellLst)
            {
                //过滤当前本身的cell
                if (item.Module == Module)
                {
                    continue;
                }
                //若cell流量是ok,则post msg变成idle
                VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(item.Module);
                if (_cellFlowOk[item.Module])
                {
                    vpwCellEntity.CheckToPostMessage(eEvent.INFO_VPW, item.Module, (int)VPWCellMsg.EnterIdle);
                }
                else//则cell流量是不ok,则post error msg
                {
                    vpwCellEntity.PostMsg((int)VPWCellMsg.Error);
                    LOG.WriteLog(eEvent.WARN_VPW, item.Module, $"cell flow {_cellFlows[item.Module]} is less than {_cellFlowStartLimit}");
                }
            }
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            List lstDevice = (List)objs[0];
            _vpwCellDevices.Clear();
            _cellFlows.Clear();
            _cellLst.Clear();
            _cellFlowOk.Clear();
            _totalFlowOk = false;
            _checkFlowOk = false;
            _totalFlow = 0;
            for (int i = 0; i < lstDevice.Count; i++)
            {
                _vpwCellDevices.Add(lstDevice[i]);
                VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(lstDevice[i].Module);
                if (vpwCellEntity.IsAuto || vpwCellEntity.IsManual)
                {
                    _cellLst.Add(lstDevice[i]);
                    if (!CheckRotationSwitchOn(lstDevice[i])){
                        return RState.Failed;
                    }
                    _cellFlowOk[lstDevice[i].Module]=false;
                }
            }
            _mainDevice = DEVICE.GetDevice(ModuleName.VPWMain1.ToString());
            _n2PurgeTime = SC.GetValue("VPWMain.Plumbing.N2PurgeTime");
            _flowFaultHolderoffTime = SC.GetValue("VPWMain.Plumbing.FlowFaultHoldoffTime");
            double purgeMotorSpeed = SC.GetValue("VPWMain.Plumbing.PurgeMotorSpeed");
            _rotationSpeed = (int)(Math.Round(purgeMotorSpeed*6,0));
            _totalFlowStartLimit = SC.GetValue("VPWMain.Plumbing.TotalFlowStartLowLimit");
            _cellFlowStartLimit = SC.GetValue("VPWMain.Plumbing.CellFlowStartLowLimit");
            _degasEnableDelayTime = SC.GetValue("VPWMain.Plumbing.DegasEnableDelayTime");
            _checkChamberUpDownTimes = SC.GetValue("VPWMain.ChamberUpDownCheckTime");
            return Runner.Start(Module,"VPW Home");
        }
        /// 
        /// 检验Rotation电机是否上电
        /// 
        /// 
        /// 
        private bool CheckRotationSwitchOn(VpwCellDevice device)
        {
            if (!device.CheckRotationSwitchOn())
            {
                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} rotation is not switch on");
                return false;
            }
            return true;
        }
    }
}