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 System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.Utilities;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.CommonData.Loader;
using CyberX8_RT.Modules.Dryer;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.WaferHolder;
using Aitex.Core.Common;
using Aitex.Core.RT.SCCore;
namespace CyberX8_RT.Modules.Loader
{
    public class LoaderLoadSideRoutine : RoutineBase, IRoutine
    {
        private enum LoadStep
        {
            SideLoad,
            SideAllLoadWait,
            LeakTest,
            LeakTestWait,
            RotationGoToTRNPA,
            RotationGoToTRNPAWait,
            UnclampWaferHolder,
            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 LoaderLoadRoutine _sideLoadRoutine;
        private LoaderCommonDevice _loaderCommonDevice;
        private bool _isSideLoaded = 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();
        /// 
        /// Flow LotTrackData
        /// 
        private List _flowDatas = new List();
        /// 
        /// Loader Start and Finish Time
        /// 
        private List _loadTimeList = new List();
        /// 
        /// 
        /// 
        private string _side = "";
        /// 
        /// WaferSize
        /// 
        private int _waferSize;
        /// 
        /// load是否完成
        /// 
        private bool _loadComplete = false;
        /// 
        /// 完成后运行
        /// 
        private string _completeSide = "TRNPA";
        #endregion
        #region 属性
        /// 
        /// UnLoad LotTrackData
        /// 
        public List LoadLotTrackDatas { get { return _datas; } }
        /// 
        /// Flow LotTrackData
        /// 
        public List FlowLotTrackDatas { get { return _flowDatas; } }
        /// 
        /// LoadTimeList
        /// 
        public List LoadTimeList { get { return _loadTimeList; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public LoaderLoadSideRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            //记录Lot track
            LottrackRecord();
            Runner.Run(LoadStep.SideLoad, () => StartLoadRoutine(_sideLoadRoutine,_isSideLoaded), _delay_1ms)
                .WaitWithStopCondition(LoadStep.SideAllLoadWait, CheckLoadAllRoutineEndStatus,CheckLoadAllRoutineStopStatus)
                .Run(LoadStep.LeakTest, StartFlowTest, _delay_1ms)
                .WaitWithStopCondition(LoadStep.LeakTestWait, CheckFlowTestEndStatus, CheckFlowTestStopStatus)
                .RunIf(LoadStep.RotationGoToTRNPA,_loadComplete,RotationGotoTransporterA,_delay_1s)
                .WaitWithStopConditionIf(LoadStep.RotationGoToTRNPAWait,_loadComplete, CheckRotationPositionStatus,CheckRotationPositionRunStop)
                .RunIf(LoadStep.UnclampWaferHolder,_loadComplete, WaferHolderClampOffAction,_delay_1ms)
                .End(LoadStep.End, UpdateWaferHolderUse, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 检验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", 2);
            }
            return result;
        }
        /// 
        /// 启动load routine
        /// 
        /// 
        /// 
        private bool StartLoadRoutine(LoaderLoadRoutine loadRoutine,bool isSideLoaded)
        {
            if (isSideLoaded)
            {
                return true;
            }
            bool result= loadRoutine.Start()==RState.Running;
            if (!result)
            {
                NotifyError(eEvent.ERR_LOADER, loadRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// 检验LoadAll完成状态
        /// 
        /// 
        private bool CheckLoadAllRoutineEndStatus()
        {
            bool sideResult = true;
            if (!_isSideLoaded)
            {
                sideResult = CheckLoadRoutineEndStatus(_sideLoadRoutine);
            }
            if (sideResult)
            {
                _loadTimeList.Add(DateTime.Now);
            }
            return sideResult;
        }
        /// 
        /// 检验LoadAll停止状态
        /// 
        /// 
        private bool CheckLoadAllRoutineStopStatus()
        {
            bool sideComplete = false;
            if(!_isSideLoaded&&!_isSideStop)
            {
                RState ret = _sideLoadRoutine.Monitor();
                _isSideStop = ret == RState.Failed || ret == RState.Timeout;
                sideComplete = (ret != RState.Running);
                if (_isSideStop)
                {
                    NotifyError(eEvent.ERR_LOADER, $"load A failed\r\n{_sideLoadRoutine.ErrorMsg}", 0);
                }
            }
            return _isSideStop;
        }
        /// 
        /// 检验routine完成状态
        /// 
        /// 
        /// 
        private bool CheckLoadRoutineEndStatus(LoaderLoadRoutine loadRoutine)
        {
            return loadRoutine.Monitor() == RState.End;
        }
        /// 
        /// 启动Flowtest
        /// 
        /// 
        private bool StartFlowTest()
        {
            bool result= _loaderCommonDevice.StartFlowTestAction();
            if (!result)
            {
                NotifyError(eEvent.ERR_LOADER, "Start Flow Test failed", 1);
            }
            return result;
        }
        /// 
        /// 检验FlowTest停止状态
        /// 
        /// 
        private bool CheckFlowTestStopStatus()
        {
            if (_loaderCommonDevice.Status == RState.Failed || _loaderCommonDevice.Status == RState.Timeout)
            {
                NotifyError(eEvent.ERR_LOADER, "Flow Test failed",1);
                return true;
            }
            return false;
        }
        /// 
        /// 检验FlowTest完成状态
        /// 
        /// 
        private bool CheckFlowTestEndStatus()
        {
            bool result = _loaderCommonDevice.Status == RState.End;
            if (result)
            {
                _flowDatas = _loaderCommonDevice.FlowLotTrackDatas;
            }
            return result;
        }
        /// 
        /// Rotation 运动至TRNPA
        /// 
        /// 
        private bool RotationGotoTransporterA()
        {
            bool result = _rotationAxis.PositionStation(_completeSide, false);
            if (!result)
            {
                NotifyError(eEvent.ERR_LOADER, $"rotation start goto {_completeSide} failed", 2);
            }
            return result;
        }
        /// 
        /// Wafer Holder Clamp Off
        /// 
        /// 
        public bool WaferHolderClampOffAction()
        {
            bool result = _loaderCommonDevice.WaferHolderClampOffAction();
            if (!result)
            {
                NotifyError(eEvent.ERR_LOADER, "Wafer Shuttle Clamp Off failed", 2);
            }
            return result;
        }
        /// 
        /// 更新WaferHolder总用量
        /// 
        /// 
        private bool UpdateWaferHolderUse()
        {
            WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder("Loader");
            if(waferHolderInfo != null)
            {
                waferHolderInfo.TotalUses += 1;
                WaferHolderManager.Instance.UpdateWaferHolderInfo(waferHolderInfo);
            }
            return true;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _side = objs[0].ToString();
            _loadComplete=(bool)objs[1];
            if (objs.Length > 2)
            {
                _completeSide= objs[2].ToString();
            }
            _waferSize = SC.GetValue($"Loader1.{_side}WaferSize");
            InitializeParameters();
            _loaderCommon = DEVICE.GetDevice($"{Module}.Common");
            _loaderSide = DEVICE.GetDevice($"{Module}.{_side}");
            //清除lotTrack数据
            _datas.Clear();
            _flowDatas.Clear();
            _loadTimeList.Clear();
            _loadTimeList.Add(DateTime.Now);
            
            return Runner.Start(Module, "Start LoadAll");
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameters()
        {
            _isSideLoaded = false;
            _isSideStop = false;
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _sideLoadRoutine = new LoaderLoadRoutine(ModuleName.Loader1.ToString(), _side);
            _loaderCommonDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.Common");
        }
        /// 
        /// 重试
        /// 
        /// 
        public RState Retry(int step)
        {
            InitializeParameters();
            List preStepIds = new List();
            _datas.Clear();
            if (step == 0 || step == -1)
            {
                string side = _side == SIDE_A ? "A" : "B";
                _isSideLoaded = CheckSideLoadCondition(side, step,false);
                return Runner.Retry(LoadStep.SideLoad, preStepIds, Module, "LoadAll Retry");
            }
            else if (step == 1)
            {
                AddPreSteps(LoadStep.LeakTest, preStepIds);
                return Runner.Retry(LoadStep.LeakTest, preStepIds, Module, $"LoadAll step {LoadStep.LeakTest} start Retry");
            }
            else
            {
                AddPreSteps(LoadStep.RotationGoToTRNPA, preStepIds);
                return Runner.Retry(LoadStep.RotationGoToTRNPA, preStepIds, Module, $"LoadAll step {LoadStep.RotationGoToTRNPA} start Retry");
            }           
        }
        /// 
        /// 忽略前
        /// 
        /// 
        /// 
        private void AddPreSteps(LoadStep step, List preStepIds)
        {
            for (int i = 0; i < (int)step; i++)
            {
                preStepIds.Add((LoadStep)i);
            }
        }
        /// 
        /// 检验前面Unload完成状态
        /// 
        /// 
        public bool CheckCompleteCondition(int index)
        {
            string side = _side == SIDE_A ? "A" : "B";
            if (!CheckSideLoadCondition(side, index,true))
            {
                return false;
            }
            JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
            double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
            if (!loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA"))
            {
                NotifyError(eEvent.ERR_LOADER, $"loader rotation {loaderRotationPosition} not in TRNPA", index);
            }
            return true;
        }
        /// 
        /// 检验Side Unload情况 
        /// 
        /// 
        /// 
        /// 
        private bool CheckSideLoadCondition(string side, int index,bool showError)
        {
            JetAxisBase shuttleAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
            double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
            if (!shuttleAxis.CheckPositionInStationIgnoreWaferSize(shuttlePosition, "MID"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in mid", index);
                }
                return false;
            }
            JetAxisBase tiltAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
            double tiltPosition = tiltAxis.MotionData.MotorPosition;
            if (tiltAxis.CheckPositionIsInStation(tiltPosition, "VERT"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in VERT", index);
                }
                return false;
            }
            JetAxisBase crsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LS{side}");
            double crsPosition = crsAxis.MotionData.MotorPosition;
            if (!crsAxis.CheckPositionIsInStation(crsPosition, "Setup"))
            {
                if (showError)
                {
                    NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Setup", 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()
        {
            LoadStep step = (LoadStep)Runner.CurrentStep;
            if (step <= LoadStep.SideAllLoadWait)
            {
                LoaderLotTrackData data = new LoaderLotTrackData();
                data.TimeStamp = DateTime.Now;
                data.LoaderABernoulliBladderEnable = _loaderSide.SideData.BernoulliBladder;
                data.LoaderABernoulliExtended = _loaderSide.SideData.BernoulliExtended;
                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;
                data.LoaderATranslatePressure = _loaderSide.SideData.TransPressure;
                data.LoaderWHClamped = _loaderCommon.CommonData.WaferHolderClamp;
                _datas.Add(data);
            }            
        }
        
    }
}