using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Loader;
using System;
using System.Collections.Generic;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.CommonData.Loader;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
namespace CyberX8_RT.Modules.Loader
{
    public class LoaderUnloadSideRoutine : RoutineBase, IRoutine
    {
        private enum UnloadStep
        {
            RotationGoToLOADA,
            RotationGoToLOADAWait,
            SideUnload,
            UnloadAllWait,
            End
        }
        #region 常量
        private const string SIDE_A = "SideA";
        private const string SIDE_B = "SideB";
        private const int LOTTRACK_TIME = 1000;
        #endregion
        #region 内部变量
        private JetAxisBase _rotationAxis;
        private string _side;
        private LoaderUnloadRoutine _sideUnloadRoutine;
        private bool _isSideUnloaded = false;
        private bool _isSideStop = false;
        /// 
        /// lotTrack time
        /// 
        private DateTime _lotTackTime = DateTime.Now;
        /// 
        /// Loader Common
        /// 
        private LoaderCommonDevice _loaderCommon;
        /// 
        /// LoaderSide
        /// 
        private LoaderSideDevice _loaderSide;
        /// 
        /// Loader LotTrackData
        /// 
        private List _datas = new List();
        /// 
        /// Wafer组
        /// 
        private string _waferGroup;
        /// 
        /// Wafer尺寸
        /// 
        private int _waferSize;
        #endregion
        #region 属性
        /// 
        /// UnLoad LotTrackData
        /// 
        public List UnloadLotTrackDatas { get { return _datas; } }
        /// 
        /// Wafer组
        /// 
        public string WaferGroup { get { return _waferGroup; } }
        /// 
        /// is SideA
        /// 
        public bool IsSideA { get { return _side == SIDE_A ? true : false; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public LoaderUnloadSideRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            LottrackRecord();
            Runner.Run(UnloadStep.RotationGoToLOADA,RotationGotoLOAD,_delay_1ms)
                .WaitWithStopCondition(UnloadStep.RotationGoToLOADAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
                .Run(UnloadStep.SideUnload, () => StartUnloadRoutine(_sideUnloadRoutine,_isSideUnloaded), _delay_1ms)
                .WaitWithStopCondition(UnloadStep.UnloadAllWait, CheckUnloadAllRoutineEndStatus,CheckUnloadAllRoutineStopStatus)
                .End(UnloadStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// Rotation Goto LOADA
        /// 
        /// 
        private bool RotationGotoLOAD()
        {
            string side = _side == SIDE_A ? "A" : "B";
            bool result = _rotationAxis.PositionStation($"LOAD{side}{_waferSize}", false);
            if (!result)
            {
                NotifyError(eEvent.ERR_LOADER, "rotation start goto LOAD failed", 0);
            }
            return result;
        }
        /// 
        /// 检验Rotation移动状态
        /// 
        /// 
        private bool CheckRotationPositionStatus()
        {
            return _rotationAxis.Status == RState.End;
        }
        /// 
        /// 检验Rotation是否还在运动
        /// 
        /// 
        private bool CheckRotationPositionRunStop()
        {
            bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout ;
            if (result)
            {
                NotifyError(eEvent.ERR_LOADER, "rotation goto position failed",0);
            }
            return result;
        }
        /// 
        /// 启动Unload routine
        /// 
        /// 
        /// 
        private bool StartUnloadRoutine(LoaderUnloadRoutine unloadRoutine,bool isSideUnloaded)
        {
            if (isSideUnloaded)
            {
                return true;
            }
            bool result= unloadRoutine.Start()==RState.Running;
            if(!result)
            {
                NotifyError(eEvent.ERR_LOADER, unloadRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// 检验UnloadAll完成状态
        /// 
        /// 
        private bool CheckUnloadAllRoutineEndStatus()
        {
            bool sideResult = true;
            if (!_isSideUnloaded)
            {
                sideResult = CheckUnloadRoutineEndStatus(_sideUnloadRoutine);
            }
            return sideResult;
        }
        /// 
        /// 检查UnloadAll停止状态
        /// 
        /// 
        private bool CheckUnloadAllRoutineStopStatus()
        {
            bool sideComplete = false;
            if (!_isSideUnloaded&&!_isSideStop)
            {
                RState ret = _sideUnloadRoutine.Monitor();
                _isSideStop = ret == RState.Failed || ret == RState.Timeout;
                sideComplete = (ret != RState.Running);
                if (_isSideStop)
                {
                    NotifyError(eEvent.ERR_LOADER, $"unload A failed\r\n{_sideUnloadRoutine.ErrorMsg}", 1);
                }
            }
            return _isSideStop;
        }
        /// 
        /// 检验routine完成状态
        /// 
        /// 
        /// 
        private bool CheckUnloadRoutineEndStatus(LoaderUnloadRoutine unloadRoutine)
        {
            return unloadRoutine.Monitor() == RState.End;
        }
        /// 
        /// 检验Routine结束状态
        /// 
        /// 
        /// 
        private bool CheckUnloadRoutineStopStatus(LoaderUnloadRoutine unloadRoutine,string side) 
        {
            RState state=unloadRoutine.Monitor();
            if (state == RState.Failed || state == RState.Timeout)
            {
                NotifyError(eEvent.ERR_LOADER, $"{side} Unload failed", 0);
                return true;
            }
            return false;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _side = objs[0].ToString();
            if (objs.Length > 1)
            {
                _waferGroup = objs[1].ToString();
            }
            LoaderEntity loaderEntity=Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
            if (_side == SIDE_A)
            {
                _waferSize = loaderEntity.SideAWaferSize;
            }
            else
            {
                _waferSize = loaderEntity.SideBWaferSize;
            }
            InitializeParameters();
            _loaderCommon = DEVICE.GetDevice($"{Module}.Common");
            _loaderSide = DEVICE.GetDevice($"{Module}.{_side}");
            //清除lotTrack数据
            _datas.Clear();
            return Runner.Start(Module, "Start Unload side");
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameters()
        {
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _sideUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), _side);
            _isSideUnloaded = false;
            _isSideStop = false;
        }
        /// 
        /// 重试
        /// 
        /// 
        public RState Retry(int step)
        {
            InitializeParameters();
            List preStepIds = new List();
            return Runner.Retry(UnloadStep.RotationGoToLOADA,preStepIds,Module,"UnloadAll Retry");
        }
        /// 
        /// 检验前面Unload完成状态
        /// 
        /// 
        public bool CheckCompleteCondition(int index)
        {
            string side = _side == SIDE_A ? "A" : "B";
            if (!CheckSideUnloadCondition(side, index,true))
            {
                return false;
            }
            return true;
        }
        /// 
        /// 检验Side Unload情况 
        /// 
        /// 
        /// 
        /// 
        private bool CheckSideUnloadCondition(string side, int index,bool showError)
        {
            JetAxisBase shuttleAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
            double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
            if (!shuttleAxis.CheckPositionInStationIgnoreWaferSize(shuttlePosition, "OUT"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in Out", index);
                }
                return false;
            }
            JetAxisBase tiltAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
            double tiltPosition = tiltAxis.MotionData.MotorPosition;
            if (!tiltAxis.CheckPositionInStationIgnoreWaferSize(tiltPosition, "HORI"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in HORI", index);
                    return false;
                }
            }
            JetAxisBase crsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LS{side}");
            double crsPosition = crsAxis.MotionData.MotorPosition;
            if (!crsAxis.CheckPositionInStationIgnoreWaferSize(crsPosition, "Unlock"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Unlock", index);
                }
                return false;
            }
            return true;
        }
        /// 
        /// 记录Lottrack
        /// 
        private void LottrackRecord()
        {
            //记录Lottrack
            if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
            {
                AddLotTrackData();
                _lotTackTime = DateTime.Now;
            }
        }
        /// 
        /// 获取Lot Track数据
        /// 
        /// 
        private void AddLotTrackData()
        {
            LoaderLotTrackData data = new LoaderLotTrackData();
            data.TimeStamp = DateTime.Now;
            if(_side == SIDE_A)
            {
                data.LoaderABernoulliBladderEnable = _loaderSide.SideData.BernoulliBladder;
                data.LoaderABernoulliBladderPressure = _loaderSide.SideData.BernoulliBladderPressure;
                data.LoaderABernoulliN2Pressure = _loaderSide.SideData.BernoulliPressure;
                data.LoaderACRSVacuum = _loaderSide.SideData.CRSVacuum;
                data.LoaderACRSVacuumAnlg = _loaderSide.SideData.CRSVacuumValue;
                data.LoaderAWHPressure = _loaderSide.SideData.WHBladderPressure;
            }
            else
            {
                data.LoaderBBernoulliBladderEnable = _loaderSide.SideData.BernoulliBladder;
                data.LoaderBBernoulliBladderPressure = _loaderSide.SideData.BernoulliBladderPressure;
                data.LoaderBBernoulliN2Pressure = _loaderSide.SideData.BernoulliPressure;
                data.LoaderBCRSVacuum = _loaderSide.SideData.CRSVacuum;
                data.LoaderBCRSVacuumAnlg = _loaderSide.SideData.CRSVacuumValue;
                data.LoaderBWHPressure = _loaderSide.SideData.WHBladderPressure;
            }          
            data.LoaderWHClamped = _loaderCommon.CommonData.WaferHolderClamp;
            _datas.Add(data);
        }
        
    }
}