using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Loader;
using CyberX8_RT.Devices.PUF;
using CyberX8_RT.Devices.TransPorter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aitex.Core.RT.SCCore;
namespace CyberX8_RT.Modules.PUF
{
    public class PufPickFromLoaderRoutine : RoutineBase,IRoutine
    {
        #region 常量
        private const string SideA = "SideA";
        private const string SideB = "SideB";
        private const string CURRENT_STATION_LIST = "CurrentStationList";
        private const string WAFER_PRESENT = "WaferPresent";
        #endregion
        private enum PufPickStep
        {
            SideConditionRoutine,
            SideConditionRoutineWait,
            RotationLoaderPickup,
            RotationLoaderPickupWait,
            ChuckOut,
            CheckChuckOut,
            VacuumOn,
            ChuckIn,
            CheckChuckIn,
            StickDistanceCheck,
            RotationHomeStation,
            RotationHomeStationWait,
            End
        }
        #region 内部变量
        private string _loaderSide;
        private string _pufSide;
        private JetAxisBase _flipAxis;
        private JetAxisBase _rotationAxis;
        private JetAxisBase _gantryAxis;
        private LoaderSideDevice _loaderSideDevice;
        private PufVacuum _vacuum;
        private PufWaferPickSubRoutine _pufWaferPickSubRoutine;
        private PufChuckRoutine _chuckRoutine;
        private PufDistanceSensor _distanceSensor;
        private bool _enableCheckStickDistanceStatus = false;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        public PufPickFromLoaderRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        public RState Monitor()
        {
            Runner.RunConditionSubRoutine(PufPickStep.SideConditionRoutine, SideConditionIndex, new IRoutine[] { _pufWaferPickSubRoutine }, new object[] { _pufSide })
                .WaitConditionSubRoutine(PufPickStep.SideConditionRoutineWait)
                .Run(PufPickStep.RotationLoaderPickup, () => { return _rotationAxis.PositionStation("LoaderPickup"); }, NullFun, 100)
                .WaitWithStopCondition(PufPickStep.RotationLoaderPickupWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
                .Run(PufPickStep.ChuckOut, () => { return _chuckRoutine.Start(true) == RState.Running; }, NullFun, 100)
                .WaitWithStopCondition(PufPickStep.CheckChuckOut, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
                .Run(PufPickStep.VacuumOn, VacuumOn, CheckWaferPresent, 5000)
                .Run(PufPickStep.ChuckIn, () => { return _chuckRoutine.Start(false) == RState.Running; }, NullFun, 100)
                .WaitWithStopCondition(PufPickStep.CheckChuckIn, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
                .Wait(PufPickStep.StickDistanceCheck, CheckStickDistanceStatus, 1000)
                .Run(PufPickStep.RotationHomeStation, () => { return _rotationAxis.PositionStation("Home"); }, NullFun, 100)
                .WaitWithStopCondition(PufPickStep.RotationHomeStationWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
                .End(PufPickStep.End, NullFun);
            return Runner.Status;
        }
        /// 
        /// Side条件获取SubRoutine索引
        /// 
        /// 
        private int SideConditionIndex()
        {
            if (_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _pufSide))
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        /// 
        /// 检验VacuumLevel
        /// 
        /// 
        private bool CheckVacuumLevel()
        {
            if (_pufSide == SideA)
            {
                return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
            }
            else if (_pufSide == SideB)
            {
                return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 检验存在Wafer
        /// 
        /// 
        private bool CheckWaferPresent()
        {
            if (_pufSide == SideA)
            {
                return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
            }
            else if (_pufSide == SideB)
            {
                return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 打开Vacuum
        /// 
        /// 
        private bool VacuumOn()
        {
            if (_pufSide == SideA)
            {
                _vacuum.VacuumAOn();
                return true;
            }
            else if (_pufSide == SideB)
            {
                _vacuum.VacuumBOn();
                return true;
            }
            return false;
        }
        /// 
        /// Stick Distance检验结果
        /// 
        /// 
        private bool CheckStickDistanceStatus()
        {
            if (_enableCheckStickDistanceStatus)
            {
                return _distanceSensor.CheckStickDistanceStatus();
            }
            else
            {
                return true;
            }
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _pufSide = objs[0].ToString();
            _flipAxis = DEVICE.GetDevice($"{Module}.Flip");
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _vacuum = DEVICE.GetDevice($"{Module}.Vacuum");
            _gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
            _distanceSensor = DEVICE.GetDevice($"{Module}.DistanceSensor");
            _pufWaferPickSubRoutine = new PufWaferPickSubRoutine(Module);
            _enableCheckStickDistanceStatus = SC.GetValue($"{Module}.EnableCheckStickDistanceStatus");
            _chuckRoutine = new PufChuckRoutine(Module);
            if (CheckCondition())
            {
                return Runner.Start(Module, "PickFrom Loader");
            }
            else
            {
                return RState.Failed;
            }
        }
        /// 
        /// 检验条件
        /// 
        /// 
        private bool CheckCondition()
        {
            //Loader1.Rotation 在LOADA
            bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1);
            if (isLoaderInstall)
            {
                JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
                double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
                if (!loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOAD"))
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Rotation {loaderRotationPosition} is not in LOAD");
                    return false;
                }
                bool isLoadA = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADA");
                bool isLoadB = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADB");
                string side = isLoadA ? "A" : "B";
                _loaderSide = isLoadA ? SideA : SideB;
                _loaderSideDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.{_loaderSide}");
                //Loader1.SwingA 在Open
                JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
                double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
                if (!loaderShuttleAAxis.CheckPositionInStationIgnoreWaferSize(loaderShuttleAPosition, "OUT"))
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleA {loaderShuttleAPosition} is not in OUT");
                    return false;
                }
                //Loader1.TiltA 在HORI
                JetAxisBase loaderTiltAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
                double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition;
                if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI"))
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Tilt{side} {loaderTiltAPosition} is not in HORI");
                    return false;
                }
                //Loader Handle Wafer状态确认
                // Lip Seal Vacuum "ON"
                if (!_loaderSideDevice.SideData.CRSVacuum)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 LS Vacuum is off");
                    return false;
                }
                //Bernoulli Bladder "ON",Retracted Green Light
                if (!_loaderSideDevice.SideData.BernoulliBladder)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Bladder is off");
                    return false;
                }
                //其他SideA/B均为OFF
                if (_loaderSideDevice.SideData.BernoulliN2)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli N2 is on");
                    return false;
                }
                if (_loaderSideDevice.SideData.WHBladder)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 WS Bladder is on");
                    return false;
                }
            }
            double rotationPosition = _rotationAxis.MotionData.MotorPosition;
            if(_rotationAxis.CheckPositionIsEmpty(rotationPosition))
            {
                LOG.WriteLog(eEvent.ERR_PUF,Module, $"rotation axis {rotationPosition} is not at Station");
                return false;
            }
            double flipPosition = _flipAxis.MotionData.MotorPosition;
            if(_flipAxis.CheckPositionIsEmpty(flipPosition))
            {
                LOG.WriteLog( eEvent.ERR_PUF,Module, $"flip axis {flipPosition} is not at Station");
                return false;
            }
            
            return true;
        }
    }
}