using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.VpwCell;
using PunkHPX8_RT.Devices.VpwMain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwCell
{
    public class VpwRecipeRoutine : RoutineBase, IRoutine
    {
        private enum RecipeStep
        {
            ChamberUp,
            CloseDrain,
            CheckLoopDO,
            VacuumPrewet,
            WaitVacuumPrewet,
            VentPrewet,
            WaitVentPrewet,
            ExtendClean,
            WaitExtendClean,
            SpinOff,
            WaitSpinOff,
            End
        }
        #region 内部变量
        /// 
        /// recipe
        /// 
        private VpwRecipe _recipe;
        /// 
        /// 设备
        /// 
        private VpwCellDevice _vpwCellDevice;
        /// 
        /// Main设备
        /// 
        private VpwMainDevice _mainDevice;
        /// 
        /// Vacuum prewet routine
        /// 
        private VpwVacuumPrewetRoutine _vacuumPrewetRoutine;
        /// 
        /// Vent Prewet
        /// 
        private VpwVentPrewetRoutine _ventPrewetRoutine;
        /// 
        /// Extend clean
        /// 
        private VpwExtendCleanRoutine _extendCleanRoutine;
        /// 
        /// Spin Off Routine
        /// 
        private VpwSpinOffRoutine _spinOffRoutine;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public VpwRecipeRoutine(string module) : base(module)
        {
            _vacuumPrewetRoutine = new VpwVacuumPrewetRoutine(Module);
            _ventPrewetRoutine = new VpwVentPrewetRoutine(module);
            _extendCleanRoutine = new VpwExtendCleanRoutine(module);
            _spinOffRoutine = new VpwSpinOffRoutine(module);
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual stop");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(RecipeStep.ChamberUp, ChamberUp, CheckChamberClosed)
                .Run(RecipeStep.CloseDrain, _vpwCellDevice.DrainValveOff, _delay_1ms)
                .Run(RecipeStep.CheckLoopDO, CheckLoopDO, _delay_1ms)
                .Run(RecipeStep.VacuumPrewet,VacuumPrewet,_delay_1ms)
                .WaitWithStopCondition(RecipeStep.WaitVacuumPrewet, () => CommonFunction.CheckRoutineEndState(_vacuumPrewetRoutine),
                    () => { return CheckSubRoutineError(_vacuumPrewetRoutine, _vacuumPrewetRoutine, 1); })
                .Run(RecipeStep.VentPrewet, VentPrewet)
                .WaitWithStopCondition(RecipeStep.WaitVentPrewet, () => CommonFunction.CheckRoutineEndState(_ventPrewetRoutine),
                    () => { return CheckSubRoutineError(_ventPrewetRoutine, _ventPrewetRoutine, 2); })
                .Run(RecipeStep.ExtendClean, ExtendClean)
                .WaitWithStopCondition(RecipeStep.WaitExtendClean, () => CommonFunction.CheckRoutineEndState(_extendCleanRoutine),
                    () => { return CheckSubRoutineError(_extendCleanRoutine, _extendCleanRoutine, 3); })
                .Run(RecipeStep.SpinOff, SpinOff)
                .WaitWithStopCondition(RecipeStep.WaitSpinOff, () => CommonFunction.CheckRoutineEndState(_spinOffRoutine),
                    () => { return CheckSubRoutineError(_spinOffRoutine, _spinOffRoutine, 4); })
                .End(RecipeStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// chamber up
        /// 
        /// 
        private bool ChamberUp()
        {
            bool result = _mainDevice.ChamberUp();
            if (!result)
            {
                NotifyError(eEvent.ERR_VPW, "chamber up failed", 0);
            }
            return result;
        }
        /// 
        /// 检验Chamber是否关闭
        /// 
        /// 
        private bool CheckChamberClosed()
        {
            bool result= _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
            if (!result)
            {
                NotifyError(eEvent.ERR_VPW, $"Chamber Closed is {_mainDevice.CommonData.ChamberClosed} and opened is {_mainDevice.CommonData.ChamberOpened}",0);
            }
            return result;
        }
        /// 
        /// 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 less than {_recipe.DiwLoopDoSet}", 0);
            }
            return result;
        }
        /// 
        /// Vacuum Prewet
        /// 
        /// 
        private bool VacuumPrewet()
        {
            bool result = _vacuumPrewetRoutine.Start(_recipe) == RState.Running;
            if (!result)
            {
                NotifyError(eEvent.ERR_VPW, _vacuumPrewetRoutine.ErrorMsg, 1);
            }
            return result;
        }
        /// 
        /// 检验Vacuum Prewet结束状态
        /// 
        /// 
        private bool CheckVacuumPrewetEndStatus()
        {
            bool result = CommonFunction.CheckRoutineEndState(_vacuumPrewetRoutine);
            return result;
        }
        /// 
        /// Vent Prewet
        /// 
        /// 
        private bool VentPrewet()
        {
            return _ventPrewetRoutine.Start(_recipe) == RState.Running;
        }
        /// 
        /// Extend Clean
        /// 
        /// 
        private bool ExtendClean()
        {
            return _extendCleanRoutine.Start(_recipe) == RState.Running;
        }
        /// 
        /// Vacuum Prewet
        /// 
        /// 
        private bool SpinOff()
        {
            return _spinOffRoutine.Start(_recipe) == RState.Running;
        }
        /// 
        /// 检验子routine异常
        /// 
        /// 
        /// 
        /// 
        /// 
        private bool CheckSubRoutineError(IRoutine routine, RoutineBase routineBase, int index)
        {
            bool result = CommonFunction.CheckRoutineStopState(routine);
            if (result)
            {
                NotifyError(eEvent.ERR_VPW, routineBase.ErrorMsg, index);
            }
            return result;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _recipe = objs[0] as VpwRecipe;
            _vpwCellDevice = DEVICE.GetDevice(Module);
            _mainDevice = DEVICE.GetDevice(ModuleName.VPWMain1.ToString());
            return Runner.Start(Module, "start run recipe");
        }
        /// 
        /// 重试
        /// 
        /// 
        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(RecipeStep.ChamberUp, preStepIds, Module, "Run recipe Retry");
        }
    }
}