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.RecipeCenter;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.SubstrateTrackings;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.AXIS;
using PunkHPX8_RT.Devices.VpwCell;
using PunkHPX8_RT.Devices.VpwMain;
using PunkHPX8_RT.Modules.VpwMain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwCell
{
    public class VpwManualPrepareRoutine : RoutineBase, IRoutine
    {
        private enum PrepareStep
        {
            CheckPreCondition,
            Purge,
            PurgeDelay,
            WaitPurge,
            CloseDrip,
            Delay,
            WaitWafer,
            ChamberUp,
            CloseDrain,
            CheckLoopDO,
            End
        }
        #region 内部变量
        /// 
        /// recipe
        /// 
        private VpwRecipe _recipe;
        /// 
        /// 电机
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// 设备
        /// 
        private VpwCellDevice _vpwCellDevice;
        /// 
        /// Main设备
        /// 
        private VpwMainDevice _mainDevice;
        /// 
        /// VPW Entity
        /// 
        private VpwMainEntity _vpwMainEntity;
        /// 
        /// 延迟时间
        /// 
        private int _putDownAfterDripClose = 2000;
        /// 
        /// 等待Wafer放入时间
        /// 
        private int _waitForWaferTime = 300000;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public VpwManualPrepareRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(PrepareStep.CheckPreCondition,CheckPreCondition,_delay_1ms)
                .RunIf(PrepareStep.Purge,_recipe.PurgeEnable,Purge,_delay_1ms)
                .DelayIf(PrepareStep.PurgeDelay, _recipe.PurgeEnable, 500)
                .WaitWithStopConditionIf(PrepareStep.WaitPurge,_recipe.PurgeEnable,CheckPurgeStatus,CheckPurgeStopStatus)
                .Run(PrepareStep.CloseDrip,()=>_vpwCellDevice.FlowDripOff(),_delay_1ms)
                .Delay(PrepareStep.Delay,_putDownAfterDripClose)
                .Wait(PrepareStep.WaitWafer,CheckWaferExsit,_waitForWaferTime)
                .Run(PrepareStep.ChamberUp,ChamberUp,CheckChamberClosed)
                .Run(PrepareStep.CloseDrain,_vpwCellDevice.DrainValveOff,_delay_1ms)
                .Run(PrepareStep.CheckLoopDO,CheckLoopDO,_delay_1ms)
                .End(PrepareStep.End,NullFun,_delay_1ms);
            return Runner.Status;
        }
        /// 
        /// Purge routine
        /// 
        /// 
        private bool Purge()
        {
            if (_vpwMainEntity == null)
            {
                NotifyError(eEvent.ERR_VPW, "VPW Main not exist", -1);
                return false;
            }
            if (_vpwMainEntity.IsIdle)
            {
                return _vpwMainEntity.CheckToPostMessage(eEvent.ERR_VPW, Module, (int)VPWMainMsg.Purge);
            }
            else if (_vpwMainEntity.State == VPWMainState.Purgeing)
            {
                return true;
            }
            else
            {
                NotifyError(eEvent.ERR_VPW, $"State {_vpwMainEntity.State} cannot purge", -1);
                return false;
            }
        }
        /// 
        /// 检验Purge执行是否结束
        /// 
        /// 
        private bool CheckPurgeStatus()
        {
            return _vpwMainEntity.IsIdle;
        }
        /// 
        /// 检验Purger执行是否出现异常
        /// 
        /// 
        private bool CheckPurgeStopStatus()
        {
            return _vpwMainEntity.IsError;
        }
        /// 
        /// 检验是否存在Wafer
        /// 
        /// 
        private bool CheckWaferExsit()
        {
            // todo 临时注释,后面需要改回来
            return WaferManager.Instance.CheckHasWafer(Module, 0);
            //return true;
        }
        /// 
        /// chamber up
        /// 
        /// 
        private bool ChamberUp()
        {
            bool result=_mainDevice.ChamberUp();
            if (!result)
            {
                NotifyError(eEvent.ERR_VPW, "chamber up failed", -1);
            }
            return result;
        }
        /// 
        /// 检验Chamber是否关闭
        /// 
        /// 
        private bool CheckChamberClosed()
        {
            return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
        }
        /// 
        /// Check LoopDO数值
        /// 
        /// 
        private bool CheckLoopDO()
        {
            if (_recipe.DiwLoopDoSet == 0)
            {
                return true;
            }
            double loopDoValue = _vpwCellDevice.LoopDOValue;
            bool result = loopDoValue < _recipe.DiwLoopDoSet;
            if (!result) 
            {
                //NotifyError(eEvent.ERR_VPW, $"LoopDO value {loopDoValue} is large than recipe set {_recipe.DiwLoopDoSet}", -1);
                LOG.WriteLog(eEvent.ERR_VPW, Module, $"LoopDO value {loopDoValue} is large than recipe set {_recipe.DiwLoopDoSet}");
            }
            return result;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _recipe=(VpwRecipe)objs[0];
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _vpwCellDevice = DEVICE.GetDevice(Module);
            _mainDevice = DEVICE.GetDevice(ModuleName.VPWMain1.ToString());
            _putDownAfterDripClose = SC.GetValue($"{Module}.PutDownAfterDripClose");
            _waitForWaferTime = SC.GetValue($"{Module}.WaitForWaferTime") * 1000;
            _vpwMainEntity = Singleton.Instance.GetModule(ModuleName.VPWMain1.ToString());
            return Runner.Start(Module, $"{Module} manual prepare");
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        private bool CheckPreCondition()
        {
            if (!_rotationAxis.IsSwitchOn)
            {
                NotifyError(eEvent.ERR_VPW,"rotaion is not switch on",-1);
                return false;
            }
            if (!_rotationAxis.IsHomed)
            {
                NotifyError(eEvent.ERR_VPW, "rotaion is not homed", -1);
                return false;
            }
            return true;
        }
        /// 
        /// 重试
        /// 
        /// 
        public RState Retry(int step)
        {
            if (_recipe == null)
            {
                NotifyError(eEvent.ERR_VPW, "recipe is null", -1);
                return RState.Failed;
            }
            List preStepIds = new List();
            return Runner.Retry(PrepareStep.CheckPreCondition, preStepIds, Module, "Prepare Retry");
        }
    }
}