using Aitex.Core.RT.Device;
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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwMain
{
    public class VpwPurgeRoutine : RoutineBase, IRoutine
    {
        private enum PurgeStep
        {
            ChameberUp,
            SetRotationSpeed,
            StartRotation,
            CheckRotationRunning,
            CloseDiwDegas,
            N2PurgeDelay,
            CloseN2Purge,
            OpenDiwDegas,
            FlowDelay,
            CheckFlow,
            CheckCellFlow,
            StopRotation,
            CheckStopStatus,
            LastHomeRotation,
            CheckLastHomeRotation,
            CheckFlowOk,
            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 VpwPurgeRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Purge abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(PurgeStep.ChameberUp, _mainDevice.ChamberUp, CheckChamberClosed, _checkChamberUpDownTimes*1000)
                .Run(PurgeStep.SetRotationSpeed, SetRotationSpeed, _delay_1s)
                .Run(PurgeStep.StartRotation, StartRotation, _delay_1ms)
                .Wait(PurgeStep.CheckRotationRunning, CheckRotationRunningStatus, 500)
                .Run(PurgeStep.CloseDiwDegas, CloseDiwDegas)
                .Delay(PurgeStep.N2PurgeDelay, _n2PurgeTime)
                .Run(PurgeStep.CloseN2Purge, _mainDevice.N2PurgeValveOff, _delay_1ms)
                .Run(PurgeStep.OpenDiwDegas, OpenDiwDegas, _delay_1ms)
                .Delay(PurgeStep.FlowDelay, _flowFaultHolderoffTime)
                .Run(PurgeStep.CheckFlow, CheckTotalFlow, _delay_1ms)
                .Run(PurgeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)
                .Run(PurgeStep.StopRotation, StopRotationAxis, _delay_1ms)
                .WaitWithStopCondition(PurgeStep.CheckStopStatus, CheckStopPostionEndStatus, CheckStopPostionStopStatus)
                .Run(PurgeStep.LastHomeRotation, HomeAllRotation, _delay_1ms)
                .WaitWithStopCondition(PurgeStep.CheckLastHomeRotation, CheckAllRotationHomeStatus, CheckAllRotationHomeStopStatus)
                .Run(PurgeStep.CheckFlowOk, CheckFlowOk, _delay_1ms)
                .RunIf(PurgeStep.ChamberDown, _checkFlowOk, () => { return _mainDevice.ChamberDown(); },
                    () => { return !_mainDevice.CommonData.ChamberClosed && _mainDevice.CommonData.ChamberOpened; })
                .Run(PurgeStep.LastCheckStatus, LastCheckResult, _delay_1ms)
                .End(PurgeStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 检验Chamber关闭
        /// 
        /// 
        private bool CheckChamberClosed()
        {
            return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
        }
        private bool SetRotationSpeed()
        {
            bool result = true;
            foreach (var item in _cellLst)
            {
                result &= item.SetRotationSpeed(_rotationSpeed);
            }
            return result;
        }
        /// 
        /// 打开所有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");
                    CloseCellDrainValve();
                    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");
                    CloseCellDrainValve();
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 关闭所有cell的Drain valve
        /// 
        private void CloseCellDrainValve()
        {
            foreach (var item in _cellLst)
            {
                item.DrainValveOff();
            }
        }
        /// 
        /// Home All Rotation
        /// 
        /// 
        private bool HomeAllRotation()
        {
            foreach (var item in _cellLst)
            {
                bool result = item.HomeRotation();
                if (!result)
                {
                    CloseCellDrainValve();
                    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.N2PurgeValveOn() ? 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 + 2;
        }
        /// 
        /// 打开DiwDegas
        /// 
        /// 
        private bool OpenDiwDegas()
        {
            return _mainDevice.DiwDegasValveOn();
        }
        /// 
        /// 检验流量
        /// 
        /// 
        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;
            }
            foreach (var item in _cellLst)
            {
                if (!_cellFlowOk[item.Module])
                {
                    _checkFlowOk = false;
                    return true;
                }
            }
            _checkFlowOk = true;
            return true;
        }
        /// 
        /// 最后确认结果
        /// 
        /// 
        private bool LastCheckResult()
        {
            AllCellPostMsg();
            if (_totalFlowOk)
            {
                return true;
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
                return false;
            }
        }
        /// 
        /// 所有cell推送消息
        /// 
        private void AllCellPostMsg()
        {
            foreach (var item in _cellLst)
            {
                VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(item.Module);
                if (!_cellFlowOk[item.Module])
                {
                    vpwCellEntity.PostMsg((int)VPWCellMsg.Error);
                    LOG.WriteLog(eEvent.WARN_VPW, item.Module, $"cell flow {_cellFlows[item.Module]} is less than {_cellFlowStartLimit}");
                }
            }
        }
        /// 
        /// 检验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;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        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(Module.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 * 360 / 60, 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 Purge");
        }
 
    }
}