using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.PUF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.Utilities;

namespace CyberX8_RT.Modules.PUF
{
    public class PufReadyForSwapRoutine : RoutineBase, IRoutine
    {
        private enum ReadyForSwapStep
        {
            VacuumOn,
            RotationHomeStation,
            RotationHomeStationWait,
            End
        }

        #region 常量 
        private const string WAFER_PRESENT = "WaferPresent";
        #endregion

        #region 内部变量
        private JetAxisBase _rotationAxis;
        private PufVacuum _vacuum;
        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="module"></param>
        public PufReadyForSwapRoutine(string module) : base(module)
        {
        }

        /// <summary>
        /// 中止
        /// </summary>
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        /// <summary>
        /// 监控
        /// </summary>
        /// <returns></returns>
        public RState Monitor()
        {
            Runner.Run(ReadyForSwapStep.VacuumOn, VacuumBOn, CheckWaferPresence, _delay_5s)
                .Run(ReadyForSwapStep.RotationHomeStation, RotationGotoHome, _delay_1ms)
                .WaitWithStopCondition(ReadyForSwapStep.RotationHomeStationWait, () => _rotationAxis.Status == RState.End, CheckRotationStopStatus)
                .End(ReadyForSwapStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// <summary>
        /// Vacuum B On
        /// </summary>
        /// <returns></returns>
        private bool VacuumBOn()
        {
            bool result = _vacuum.VacuumBOn();
            if(!result)
            {
                NotifyError(eEvent.ERR_PUF, "side B Vacuum on failed", 0);
            }
            return result;
        }
        /// <summary>
        /// 检验是否存在Wafer
        /// </summary>
        /// <returns></returns>
        private bool CheckWaferPresence()
        {
            return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
        }
        /// <summary>
        /// Rotation Goto Park
        /// </summary>
        /// <returns></returns>
        private bool RotationGotoHome()
        {
            bool result = _rotationAxis.PositionStation("Home");
            if (!result)
            {
                NotifyError(eEvent.ERR_PUF, "rotation goto Home failed", 0);
            }
            return result;
        }
        /// <summary>
        /// 检验Rotation异常状态
        /// </summary>
        /// <returns></returns>
        private bool CheckRotationStopStatus()
        {
            bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout;
            if (result)
            {
                NotifyError(eEvent.ERR_PUF, "rotaion motion failed", 0);
            }
            return result;
        }
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        public RState Start(params object[] objs)
        {
            InitializeParameters();
            return Runner.Start(Module, "Start Go to Park For Swap");
        }
        /// <summary>
        /// 初始化参数
        /// </summary>
        private void InitializeParameters()
        {
            _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
            _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");
        }
        /// <summary>
        /// 重试
        /// </summary>
        /// <param name="step"></param>
        public RState Retry(int step)
        {
            InitializeParameters();
            List<Enum> preStepIds = new List<Enum>();
            return Runner.Retry(ReadyForSwapStep.VacuumOn, preStepIds, Module, "ReadyForSwap Retry");
        }
        /// <summary>
        /// 检验完成情况 
        /// </summary>
        /// <returns></returns>
        public bool CheckCompleteCondition()
        {
            double rotationPosition = _rotationAxis.MotionData.MotorPosition;
            if (!_rotationAxis.CheckPositionIsInStation(rotationPosition, "Home"))
            {
                NotifyError(eEvent.ERR_PUF, $"rotation {rotationPosition} not in Home", 0);
                return false;
            }
            return true;
        }
    }
}