using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.PUF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.SubstrateTrackings;
using CyberX8_RT.Modules.Metal;
using CyberX8_RT.Devices.AXIS;
using Aitex.Core.RT.Device;
namespace CyberX8_RT.Schedulers.Loader
{
    public class SchedulerLoader : SchedulerModule
    {
        private enum SchedulerStep
        {
            WaitLoad,
            LoadingFirst,
            ReadyForPuf,
            LoadingSecond
        }
        #region 内部变量
        private LoaderEntity _loaderEntity;
        private PUFEntity _puf1Entity;
        private SchedulerStep _currentStep;
        private int _currentWaferIndex = 1;
        #endregion
        #region 属性
        public override bool IsIdle
        {
            get { return _state == RState.End; }
        }
        public override bool IsError
        {
            get { return _state == RState.Failed || _state == RState.Timeout; }
        }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SchedulerLoader(ModuleName module) : base(module.ToString())
        {
            _loaderEntity = Singleton.Instance.GetModule(module.ToString());
            _puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString());
        }
        /// 
        /// 执行
        /// 
        /// 
        /// 
        public override bool RunProcess(object recipe, object parameter, List syncModuleMessages)
        {
            _state = RState.Running;
            _currentStep = SchedulerStep.WaitLoad;
            _currentWaferIndex = 1;
            return true;
        }
        /// 
        /// 监控执行
        /// 
        /// 
        public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
        {
            int waferTaskCount =(int)schedulerSequence.Parameters;
            bool loadComplete = waferTaskCount == _currentWaferIndex;
            if (_currentStep == SchedulerStep.WaitLoad)
            {
                if (_loaderEntity.State != (int)LOADERSTATE.WaitForLoad)
                {
                    return false;
                }
                bool result = ExecuteLoadSide(loadComplete);
                if (result)
                {
                    _currentStep = SchedulerStep.LoadingFirst;
                }
            }
            else if (_currentStep == SchedulerStep.LoadingFirst)
            {
                if (_loaderEntity.IsIdle)
                {
                    if (waferTaskCount == 1)
                    {
                        _state = RState.End;
                    }
                    else
                    {
                        bool result = EnterReadyForPuf();
                        if (result)
                        {
                            _currentStep = SchedulerStep.ReadyForPuf;
                            _currentWaferIndex=2;
                        }
                    }
                }
            }
            else if (_currentStep == SchedulerStep.ReadyForPuf)
            {
                if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
                {
                    bool result = ExecuteLoadSide(true);
                    if (result)
                    {
                        _currentStep = SchedulerStep.LoadingSecond;
                    }
                }
            }
            else if (_currentStep == SchedulerStep.LoadingSecond)
            {
                if (_loaderEntity.IsIdle)
                {
                    _state = RState.End;
                }
            }
            return true;
        }
        private bool ExecuteLoadSide(bool loadComplete)
        {
            if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation || (_puf1Entity.IsIdle && _puf1Entity.IsBackToParkStation))
            {
                JetAxisBase tiltAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltA");
                JetAxisBase tiltBAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltB");
                double tiltAPosition = tiltAAxis.MotionData.MotorPosition;
                double tiltBPosition = tiltBAxis.MotionData.MotorPosition;
                bool tiltAHori = tiltAAxis.CheckPositionIsInStation(tiltAPosition, "HORI");
                bool tiltBHori = tiltBAxis.CheckPositionIsInStation(tiltBPosition, "HORI");
                string side = tiltAHori ? "SideA" : (tiltBHori ? "SideB" : "");
                if (string.IsNullOrEmpty(side))
                {
                    return false;
                }
                return _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(),
                    (int)LoaderMSG.LoadSide, side, loadComplete);
            }
            return false;
        } 
        /// 
        /// 第二次进入WaitForUnload
        /// 
        /// 
        private bool EnterReadyForPuf()
        {
            return _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(),
                (int)LoaderMSG.ReadyForPuf);
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        /// 
        /// 
        public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason)
        {
            if (_state == RState.Running)
            {
                reason = "scheduler module is already running";
                return false;
            }
            if (_loaderEntity.IsIdle)
            {
                reason = "loader is idle";
                return false;
            }
            if (_loaderEntity.WaferHolderInfo == null)
            {
                reason = "loader has no wafer shuttle";
                return false;
            }
            if (_loaderEntity.WaferHolderInfo.Id != materialId)
            {
                reason = $"{_loaderEntity.Module} wafer shuttle {_loaderEntity.WaferHolderInfo.Id} is not matched with {materialId}";
                return false;
            }
            return true;
        }
    }
}