using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.ToolLayout;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.AXIS;
using PunkHPX8_RT.Devices.PlatingCell;
using PunkHPX8_RT.Devices.Reservoir;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace PunkHPX8_RT.Modules.PlatingCell
{
    public class PlatingCellInitializeRoutine : RoutineBase, IRoutine
    {
        private enum InitializeStep
        {
            CheckPowerSupplierConnected,
            CheckClamShellClosed,
            VerticalGotoLoad,
            VerticalGotoLoadCheck,
            RotationHome,
            RotationHomeCheck,
            AngleEntryTilt,
            AngleEntryVertical,
            CheckClamShellOpen,
            OpenCAAndANIsoltaionValve,
            CheckCellFlowWait,
            CheckCellFlow,
            OpenCCRAndRinseValve,
            RinseDripIdleDelay,
            CloseCCRAndRinseValve,
            End
        }
        #region 内部变量
        /// 
        /// 持久化对象
        /// 
        private PlatingCellPersistentValue _persistentValue;
        /// 
        /// 设备对象
        /// 
        private PlatingCellDevice _platingCellDevice;
        /// 
        /// 槽体对象
        /// 
        private ReservoirDevice _reservoirDevice;
        /// 
        /// Reservoir Recipe
        /// 
        private ResRecipe _resRecipe;
        /// 
        /// vertical axis
        /// 
        private JetAxisBase _verticalAxis; 
        /// 
        /// Rotation axis
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// _flowFaultHoldOffTime 单位ms
        /// 
        private int _flowFaultHoldOffTime = 1000;
        /// 
        /// Cell Flow Start Low Limit
        /// 
        private double _cellFlowStartLowLimit = 3.0;
        /// 
        /// Anode flow start low limit
        /// 
        private double _anFlowStartLowLimit = 0.5;
        /// 
        /// Rinse Drip Idle Period
        /// 
        private int _rinseDripIdlePeriod = 1000;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PlatingCellInitializeRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(InitializeStep.CheckPowerSupplierConnected, CheckPowerSupplierStatus, _delay_1ms)
                .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellClose(), CheckClamShellClosed, _delay_1ms)
                .Run(InitializeStep.VerticalGotoLoad, VerticalGotoLoad, NullFun, 100)
                .WaitWithStopCondition(InitializeStep.VerticalGotoLoadCheck, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
                .Run(InitializeStep.RotationHome, RotationGotoHome, NullFun, 100)
                .WaitWithStopCondition(InitializeStep.RotationHomeCheck, CheckRotationPositionStatus, CheckRotationPositionRunStop)
                .Run(InitializeStep.AngleEntryTilt, () => _platingCellDevice.HeadtTiltAction(), CheckAngleTilt, _delay_1ms)
                .Run(InitializeStep.AngleEntryVertical, () => _platingCellDevice.HeadtVerticalAction(), CheckAngleVertical, _delay_1ms)
                .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellOpen(), CheckClamShellOpen, _delay_1ms)
                .Run(InitializeStep.OpenCAAndANIsoltaionValve, OpenReservoirIsolationValve,_delay_1ms)
                .Delay(InitializeStep.CheckCellFlowWait, _flowFaultHoldOffTime)
                .Run(InitializeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)
                .Run(InitializeStep.OpenCCRAndRinseValve, OpenCCRAndRinseValve, _delay_1ms)
                .Delay(InitializeStep.RinseDripIdleDelay, _rinseDripIdlePeriod)
                .Run(InitializeStep.CloseCCRAndRinseValve, CloseCCRAndRinseValve, _delay_1ms)
                .End(InitializeStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 检查cell flow
        /// 
        /// 
        private bool CheckCellFlow()
        {
            if ("Manual".Equals(_persistentValue.OperatingMode))
            {
                if(_reservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than cellFlowStartLowLimit{_cellFlowStartLowLimit}");
                    _reservoirDevice.CAIsolationOff();
                    return false;
                }
                if (_reservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than cellFlowStartLowLimit{_anFlowStartLowLimit}");
                    _reservoirDevice.ANIsolationOff();
                    return false;
                }
            }
            else
            {
                if (_reservoirDevice.ReservoirData.CaFlow < _resRecipe.CAFlowRateErrorLow)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than resRecipe CAFlowRateErrorLow{_resRecipe.CAFlowRateErrorLow}");
                    return false;
                }
                if (_reservoirDevice.ReservoirData.AnFlow < _resRecipe.ANFlowRateErrorLow)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than resRecipe ANFlowRateErrorLow{_resRecipe.ANFlowRateErrorLow}");
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 打开reservoir Isolation valve
        /// 
        /// 
        private bool OpenReservoirIsolationValve()
        {
            return _reservoirDevice.ANIsolationOn() && _reservoirDevice.ANIsolationOn();
        }
        /// 
        /// 打开CCR/Rinse valve
        /// 
        /// 
        private bool OpenCCRAndRinseValve()
        {
            return _platingCellDevice.CCREnableAction() && _platingCellDevice.RinseEnableAction();
        }
        /// 
        /// 关闭CCR/Rinse valve
        /// 
        /// 
        private bool CloseCCRAndRinseValve()
        {
            return _platingCellDevice.CCRDisableAction() && _platingCellDevice.RinseDisableAction();
        }
        /// 
        /// vertical 运动到Load位置
        /// 
        /// 
        private bool VerticalGotoLoad()
        {
            if(_verticalAxis != null )
            {
                if (!_verticalAxis.IsSwitchOn)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Power On");
                    return false;
                }
                else if (!_verticalAxis.IsHomed)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Home,Home vertical first");
                    return false;
                }
                return _verticalAxis.PositionStation("Load", true);
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "vertical axis is null");
                return false;
            }   
        }
        /// 
        /// vertical 运动到Load位置
        /// 
        /// 
        private bool RotationGotoHome()
        {
            if (_rotationAxis != null)
            {
                if (!_rotationAxis.IsSwitchOn)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Roation is not Power On");
                    return false;
                }
                else if (!_rotationAxis.IsHomed)
                {
                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation is not Home,Home Rotation first");
                    return false;
                }
                return _rotationAxis.PositionStation("Home", true);
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation axis is null");
                return false;
            }
        }
        /// 
        /// 检查ClamShell是否closed
        /// 
        /// 
        private bool CheckClamShellClosed()
        {
            return _platingCellDevice.PlatingCellDeviceData.ClamShellClose;
        }
        /// 
        /// 检查ClamShell是否Open
        /// 
        /// 
        private bool CheckClamShellOpen()
        {
            return !_platingCellDevice.PlatingCellDeviceData.ClamShellClose;
        }
        /// 
        /// 检查Angle是否Tilt
        /// 
        /// 
        private bool CheckAngleTilt()
        {
            return _platingCellDevice.PlatingCellDeviceData.HeadTilt;
        }
        /// 
        /// 检查Angle是否Vertical
        /// 
        /// 
        private bool CheckAngleVertical()
        {
            return !_platingCellDevice.PlatingCellDeviceData.HeadTilt;
        }
        /// 
        /// 检验Metal A/B 面PowerSupplier通讯状况
        /// 
        /// 
        private bool CheckPowerSupplierStatus()
        {
            if (!_platingCellDevice.PowerSupplier.IsConnected)
            {
                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "power is not connected");
                return false;
            }
            return true;
        }
        /// 
        /// 检验Vertical移动状态
        /// 
        /// 
        private bool CheckVerticalPositionStatus()
        {
            return _verticalAxis.Status == RState.End;
        }
        /// 
        /// 检验Vertical是否还在运动
        /// 
        /// 
        private bool CheckVerticalPositionRunStop()
        {
            return _verticalAxis.Status == RState.Failed;
        }
        /// 
        /// 检验Rotation移动状态
        /// 
        /// 
        private bool CheckRotationPositionStatus()
        {
            return _rotationAxis.Status == RState.End;
        }
        /// 
        /// 检验Rotaion是否还在运动
        /// 
        /// 
        private bool CheckRotationPositionRunStop()
        {
            return _rotationAxis.Status == RState.Failed;
        }
        /// 
        /// 获取Reservoir设备
        /// 
        /// 
        private ReservoirDevice GetReservoirDevice()
        {
            string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
            return DEVICE.GetDevice(reservoir);
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _persistentValue = (PlatingCellPersistentValue)objs[0];
            _platingCellDevice = DEVICE.GetDevice(Module);
            _reservoirDevice = GetReservoirDevice();
            _flowFaultHoldOffTime = SC.GetValue("PlatingCell.FlowFaultHoldOffTime");
            _rinseDripIdlePeriod = SC.GetValue("PlatingCell.RinseDripIdlePeriod");
            _cellFlowStartLowLimit = SC.GetValue("PlatingCell.CellFlowStartLowLimit");
            _anFlowStartLowLimit = SC.GetValue("PlatingCell.ANFlowStartLowLimit");
            if("PlatingCell1".Equals(Module) || "PlatingCell2".Equals(Module))
            {
                _verticalAxis = DEVICE.GetDevice("PlatingCell1_2.Vertical");
            }
            else
            {
                _verticalAxis = DEVICE.GetDevice("PlatingCell3_4.Vertical");
            }
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
            ReservoirDevice reservoirDevice = DEVICE.GetDevice(reservoir);
            if (reservoirDevice == null)
            {
                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} device is null");
                return RState.Failed;
            }
            if (reservoirDevice.Recipe == null)
            {
                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} current recipe is null");
                return RState.Failed;
            }
            _resRecipe = reservoirDevice.Recipe;
            return Runner.Start(Module, "Start Reservoir Initialize");
        }
    }
}