using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.RecipeCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Facilities;
using CyberX8_RT.Devices.SRD;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace CyberX8_RT.Modules.SRD
{
    internal class SRDPresenceTestRoutine : RoutineBase, IRoutine
    {
        private enum PresenceTestStep
        {
            Ready,           
            CloseDoor,
            CheckCloseDoor,
            ChuckVacuumOn,
            RunWafer,
            RunWaferWait,
            InitialUnloadingStateMachine,
            Unloading,
            UnloadingWait,
            End
        }
        #region 内部变量
        /// 
        /// Rotation Axis
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// Arm Axis
        /// 
        private JetAxisBase _armAxis;
        /// 
        /// SRD Common
        /// 
        private SrdCommonDevice _srdCommon;
        /// 
        /// recipe名称
        /// 
        private string _recipe;
        /// 
        /// SRD Recipe
        /// 
        private SrdRecipe _srdRecipe;
        /// 
        /// Module
        /// 
        private string _module;
        /// 
        /// Wafer Presence Test功能是否启用
        /// 
        private bool _presenceTestEnabled;
        /// 
        /// Run wafer Recipe Routine
        /// 
        private SRDRunWaferRecipeRoutine _runWaferRecipRoutine;
        /// 
        /// Unload Routine
        /// 
        private SRDUnloadRoutine _unloadRoutine;
        #endregion
        #region 属性
        /// 
        /// 当前子状态机
        /// 
        public string CurrentStateMachine
        {
            get { return GetCurrentStateMachine(); }
        }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SRDPresenceTestRoutine(string module) : base(module)
        {
            _module = module;
            _srdCommon = DEVICE.GetDevice($"{module}.Common");
            _runWaferRecipRoutine = new SRDRunWaferRecipeRoutine(module);
            _unloadRoutine = new SRDUnloadRoutine(module);
        }
        /// 
        /// Abort
        /// 
        public void Abort()
        {
            if(_unloadRoutine.Monitor() == RState.Running)
            {
                _unloadRoutine.Abort();
            }
            if (_runWaferRecipRoutine.Monitor() == RState.Running)
            {
                _runWaferRecipRoutine.Abort();
            }          
            Runner.Stop("Presence Test Abort");
            if (_srdCommon != null)
            {
                _srdCommon.EnterErrorOperation();
            }
        }
        public RState Monitor()
        {
            Runner.Wait(PresenceTestStep.Ready, CheckReadyStatus, _delay_1ms)
                .Run(PresenceTestStep.CloseDoor, CloseDoor, CheckDoorClosed, _delay_1s)
                .Run(PresenceTestStep.ChuckVacuumOn, EngageChuckVacuum, CheckVacuum, _delay_1s)
                .Run(PresenceTestStep.RunWafer, () => { return StartRunWaferRecipeRoutine(_recipe); }, _delay_1ms)
                .WaitWithStopCondition(PresenceTestStep.RunWaferWait, CheckRunWaferRoutineCompleteStatus, CheckRunWaferRoutineErrorStatus)
                .Run(PresenceTestStep.Unloading, () => { return StartUnloadingRoutine(); }, _delay_1ms)
                .WaitWithStopCondition(PresenceTestStep.UnloadingWait, CheckUnloadingRoutineCompleteStatus, CheckUnloadingRoutineErrorStatus)
                .End(PresenceTestStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _recipe = objs[0].ToString();          
            _srdRecipe = RecipeFileManager.Instance.LoadGenericityRecipe(_recipe);
            if (_srdRecipe == null)
            {
                LOG.WriteLog(eEvent.INFO_SRD, Module.ToString(), $"Start Run Wafer State Machine, recipe[{_recipe}] is null");
                return RState.Failed;
            }
            Runner.Start(Module, "PresenceTest");
            return RState.Running;
        }
        private bool CheckReadyStatus()
        {
            //Arm是否开启,是否home
            _armAxis = DEVICE.GetDevice($"{_module}.Arm");
            if (_armAxis.IsSwitchOn)
            {
                if (!_armAxis.IsHomed)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, _module, "Arm is not swicth on");
                    return false;
                }
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_SRD, _module, "Arm is not home");
                return false;
            }            
            //Rotation是否开启,是否home
            _rotationAxis = DEVICE.GetDevice($"{_module}.Rotation");
            if (_rotationAxis.IsSwitchOn)
            {
                if (!_rotationAxis.IsHomed)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, _module, "Rotation is not homed");
                    return false;
                }
            }
            else
            {
                
                LOG.WriteLog(eEvent.ERR_SRD, _module, "Rotation is not switched on ");
                return false;
                
            }
            //检查N2与CDA
            SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities");
            var result = systemFacilities.CheckCDAN2();
            if (!result.result)
            {
                LOG.WriteLog(eEvent.ERR_SRD, _module, $"CheckCDAN2 is failed");
                return false;
            }
         
            //Wafer Presence Test功能是否开启
            if (SC.ContainsItem($"SRD.{_module}EnablePresenceCheckvalue"))
            {
                _presenceTestEnabled = SC.GetValue($"SRD.{_module}EnablePresenceCheckvalue");
                if (!_presenceTestEnabled)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, _module, $"{_module}EnablePresenceCheckvalue is unable");
                    return false;
                }
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_SRD, _module, $"Config dosen't have EnablePresenceCheckvalue");
                return false;
            }
            return true;
        }
        /// 
        /// Close Door
        /// 
        /// 
        /// 
        private bool CloseDoor()
        {
            bool result = _srdCommon.DoorCloseAction("", null);
            if (!result)
            {
                return false;
            }
            return result;
        }
        /// 
        /// 检验DoorClosed
        /// 
        /// 
        /// 
        private bool CheckDoorClosed()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {               
                return false;
            }
            return _srdCommon.Status == RState.End && _srdCommon.CommonData.DoorClosed;
        }
        /// 
        /// Chuck Vacuum On
        /// 
        /// 
        /// 
        private bool EngageChuckVacuum()
        {
            bool result = _srdCommon.ChuckVacuumOnAction("", null);
            if (!result)
            {
                return false;
            }
            return result;
        }
        /// 
        /// 检查真空状态
        /// 
        /// 
        /// 
        private bool CheckVacuum()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {
                return false;
            }
            return _srdCommon.Status == RState.End && !_srdCommon.CommonData.ChuckVacuum;
        }
        #region SRD RunWaferRecipeRoutine
        /// 
        /// 启动RunWaferRecipeRoutine
        /// 
        /// 
        /// 
        private bool StartRunWaferRecipeRoutine(string recipe)
        {
            bool presenceTestFlag = true;
            return _runWaferRecipRoutine.Start(_srdRecipe, presenceTestFlag) == RState.Running;
        }
        /// 
        /// 检验RunWaferRecipeRoutine是否完成
        /// 
        /// 
        private bool CheckRunWaferRoutineCompleteStatus()
        {
            return CommonFunction.CheckRoutineEndState(_runWaferRecipRoutine);
        }
        /// 
        /// 检验RunWaferRecipeRoutine是否出错
        /// 
        /// 
        private bool CheckRunWaferRoutineErrorStatus()
        {
            bool result = CommonFunction.CheckRoutineStopState(_runWaferRecipRoutine);
            if (result && _srdCommon != null)
            {
                _srdCommon.EnterErrorOperation();
            }
            return result;
        }
        #endregion
        #region SRD UnloadingRoutine
        /// 
        /// 启动UnloadingRoutine
        /// 
        /// 
        /// 
        private bool StartUnloadingRoutine()
        {
            return _unloadRoutine.Start() == RState.Running;
        }
        /// 
        /// 检验UnloadingRoutine是否完成
        /// 
        /// 
        private bool CheckUnloadingRoutineCompleteStatus()
        {
            return CommonFunction.CheckRoutineEndState(_unloadRoutine);
        }
        /// 
        /// 检验UnloadingRoutine是否出错
        /// 
        /// 
        private bool CheckUnloadingRoutineErrorStatus()
        {
            return CommonFunction.CheckRoutineStopState(_unloadRoutine);
        }
        
        #endregion
        /// 
        /// 获取当前子状态机
        /// 
        private string GetCurrentStateMachine()
        {
            string result;
            if (Runner.CurrentStep.ToString() == "Ready")
            {
                result = "Ready";
            }
            else if (Runner.CurrentStep.ToString().Contains("RunWafer"))
            {
                result = _runWaferRecipRoutine.CurrentStep;
            }
            else if (Runner.CurrentStep.ToString().Contains("Unloading"))
            {
                result = _unloadRoutine.CurrentStep;
            }
            else
            {
                result = "End";
            }
            return result;
        }
    }
}