using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.PUF;
using CyberX8_RT.Modules;
using CyberX8_RT.Schedulers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
using Aitex.Core.Common;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Jobs;
using Aitex.Core.RT.Fsm;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.ToolLayout;
using Aitex.Core.RT.Routine;
using CyberX8_RT.Schedulers.Transporter;

namespace CyberX8_RT.Dispatch
{
    public enum WaferHolderTaskState
    {
        Created,
        Processing,
        End,
        Error,
        Canceled
    }
    /// <summary>
    /// WaferHolder
    /// </summary>
    /// <param name="info"></param>
    /// <param name="schedulerSequence"></param>
    public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence);
    /// <summary>
    /// WaferHolderTask完成
    /// </summary>
    /// <param name="id"></param>
    public delegate void WaferHolderTaskComplete(string id);
    public class WaferHolderTask
    {
        #region 内部变量
        /// <summary>
        /// 调度步骤
        /// </summary>
        private List<SchedulerSequence> _schedulerSequences;
        /// <summary>
        /// 当前步骤索引
        /// </summary>
        private int _currentSequenceIndex = 0;

        /// <summary>
        /// PUF实例
        /// </summary>
        private PUFEntity _puf1Entity;

        /// <summary>
        /// PUF实例
        /// </summary>
        private PUFEntity _puf2Entity;
        /// <summary>
        /// 是否开始执行
        /// </summary>
        private bool _isStart = false;

        /// <summary>
        /// 暂停时的索引
        /// </summary>
        private int _pausedIndex = -1;
        /// <summary>
        /// 错误上升触发
        /// </summary>
        private R_TRIG _sequenceErrorTigger = new R_TRIG();
        /// <summary>
        /// Sequence类型
        /// </summary>
        private string _sequenceType = "";
        /// <summary>
        /// FA回复
        /// </summary>
        private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
        #endregion

        #region 属性
        /// <summary>
        /// ID 
        /// </summary>
        public string ID { get;private set; }   
        /// <summary>
        /// WaferHolder属性
        /// </summary>
        public WaferHolderInfo WaferHolderInfo { get;private set; }
        /// <summary>
        /// Process Job信息
        /// </summary>
        public ProcessJobInfo ProcessJobInfo { get;private set; }
        /// <summary>
        /// 状态
        /// </summary>
        public WaferHolderTaskState State { get; private set; }
        /// <summary>
        /// 步骤完成事件
        /// </summary>
        public event WaferHolderSchedulerComplete OnSchedulerComplete;
        /// <summary>
        /// 任务完成事件
        /// </summary>
        public event WaferHolderTaskComplete OnTaskComplete;
        /// <summary>
        /// 调度集合
        /// </summary>
        public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="waferHolderInfo"></param>
        /// <param name="schedulerSequences"></param>
        public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)
        {
            ID=Guid.NewGuid().ToString();
            WaferHolderInfo=waferHolderInfo;
            WaferHolderInfo.Status = WaferHolderStatus.Normal;
            if (processJobInfo != null)
            {
                WaferHolderInfo.SequenceId = processJobInfo.SequenceRecipe.Ppid;
                WaferHolderInfo.SequenceRecipe = processJobInfo.SequenceRecipe;
                _sequenceType = processJobInfo.SequenceRecipe.SequenceType;
                WaferHolderInfo.CurrentControlJobId = processJobInfo.ControlJobName;
                WaferHolderInfo.LotId = processJobInfo.LotName;
            }
            else
            {
                AnalyseProductionProcessJobInfo();
            }
            ProcessJobInfo=processJobInfo;
            State = WaferHolderTaskState.Created;
            _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
            _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
        }
        /// <summary>
        /// 初始化调度步骤
        /// </summary>
        /// <param name="schedulers"></param>
        public void InitialSchedulers(List<SchedulerSequence> schedulers)
        {
            _schedulerSequences = schedulers;
        }
        /// <summary>
        /// 分析生产片的ProcessJob信息
        /// </summary>
        private void AnalyseProductionProcessJobInfo()
        {
            if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
            {
                WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
                if (waferAInfo != null && waferAInfo.WaferType == WaferType.Production)
                {
                    ProcessJobInfo = waferAInfo.ProcessJob;
                    _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
                    WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
                    WaferHolderInfo.LotId = ProcessJobInfo.LotName;
                    WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;
                    return;
                }
            }
            if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
            {
                WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
                if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)
                {
                    ProcessJobInfo = waferBInfo.ProcessJob;
                    _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
                    WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
                    WaferHolderInfo.LotId = ProcessJobInfo.LotName;
                    WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;
                }
            }
        }
        /// <summary>
        /// 执行
        /// </summary>
        public void Run()
        {
            if(_currentSequenceIndex>=_schedulerSequences.Count)
            {
                State = WaferHolderTaskState.End;
                if(OnTaskComplete!=null)
                {
                    OnTaskComplete(ID);
                }
                FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
                return;
            }

            if (!_isStart)
            {
                bool preCondition = CheckStartCondition();
                if (!preCondition)
                {
                    return;
                }
                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} prepare Start {_currentSequenceIndex + 1} sequence");
                _isStart = true;
                if (WaferHolderInfo.SchedulerModules == null)
                {
                    WaferHolderInfo.SchedulerModules = new List<string>();
                }
                WaferHolderInfo.SchedulerModules.Clear();
            }
            SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
            //暂停中
            if (sequence.State == RState.Init && _currentSequenceIndex >= _pausedIndex && _pausedIndex != -1)
            {
                return;
            }
            if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)
            {
                State=WaferHolderTaskState.End;
                if (OnTaskComplete != null)
                {
                    OnTaskComplete(ID);
                }
                FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
                return;
            }
            if(_currentSequenceIndex<_schedulerSequences.Count)
            {
                if(sequence.State==RState.Init)
                {
                    if(sequence.SchedulerModule==null)
                    {
                        return;
                    }
                    if(!BufferWaferHolderJudgeResource(sequence))
                    {
                        return;
                    }
                    string reason = "";
                    bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex, sequence.Parameters,WaferHolderInfo.Id,ref reason);
                    if (sequeceCondition)
                    {
                        bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters, sequence.SynchronousModuleMessages);
                        if (result)
                        {
                            if (State == WaferHolderTaskState.Created)
                            {
                                State = WaferHolderTaskState.Processing;
                                FaModuleNotifier.Instance.NotifyWaferShuttleJobStart(WaferHolderInfo);
                            }
                            sequence.State = RState.Running;
                            sequence.StartTime = DateTime.Now;
                            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");
                        }
                        else
                        {                           
                            if (sequence.ModuleName == ModuleName.Transporter1&&sequence.NextModuleType==ModuleType.Metal)
                            {
                                if (!CheckAfterMetalAvaible())
                                {
                                    LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} has no avaible metal");
                                    TransporterAction action = sequence.Parameters as TransporterAction;
                                    if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
                                    {
                                        WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
                                        waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
                                        waferHolderMoveItem.DestModule = ModuleName.Unknown;
                                        LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} next sequence changed to dryer");
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        _sequenceErrorTigger.CLK = !sequeceCondition;
                        if (_sequenceErrorTigger.Q)
                        {
                            LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");
                        }
                    }
                }
                else if(sequence.State==RState.Running)
                {
                    sequence.SchedulerModule.MonitorProcess(sequence,false);
                    _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;
                    if (sequence.SchedulerModule.IsError)
                    {
                        //用于LoadTransporter取的WaferHolder Id不一致,则取消当前WaferHolderTask
                        if (sequence.ModuleName == ModuleName.Transporter2)
                        {
                            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,task canceled");
                            State = WaferHolderTaskState.Canceled;
                            return;
                        }
                        if (_sequenceErrorTigger.Q)
                        {
                            AnalyseSchedulerErrorState(sequence);
                        }
                    }
                    else if(sequence.SchedulerModule.IsIdle)
                    {
                        sequence.EndTime = DateTime.Now;
                        sequence.State = RState.End;
                        sequence.ProcessMilliSeconds=sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;

                        if(sequence.IsProcessSequece)
                        {
                            UpdateWaferHolderProcessingStatus();
                        }
                        if(sequence.IsLastProcessSequence)
                        {
                            UpdateWaferHolderProcessComplete();
                        }
                        if (OnSchedulerComplete != null)
                        {
                            OnSchedulerComplete(WaferHolderInfo, sequence);
                        }

                        UpdateLoaderToBufferWaferHolderToloaderStatus(sequence);
                        LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
                        _currentSequenceIndex++; 
                        AutoChangeLoaderTransporterScheduler();
                        //检验rinse后面是否存在可用的Metal
                        if (sequence.ModuleType == ModuleType.Rinse)
                        {
                            AnalyseRinseAfterMetalAvaible(sequence);
                        }
                        else if (sequence.ModuleType == ModuleType.Prewet)
                        {
                            AnalysePrewetAfterMetalAvaible(sequence);
                        }
                    }
                }
                else if (sequence.State == RState.End)
                {
                    LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence is End");
                    _currentSequenceIndex++;
                }
            }
        }

        /// <summary>
        /// 更新任务结束
        /// </summary>
        public void UpdateDryerLastSchedulerComplete()
        {
            SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
            sequence.EndTime = DateTime.Now;
            sequence.State = RState.End;
            sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
            LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex+1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
            State = WaferHolderTaskState.End;
            if (OnTaskComplete != null)
            {
                OnTaskComplete(ID);
            }
            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
        }
        /// <summary>
        /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader
        /// </summary>
        /// <param name="sequence"></param>
        private void UpdateLoaderToBufferWaferHolderToloaderStatus(SchedulerSequence sequence)
        {
            string currentLocation = WaferHolderInfo.CurrentLocation;
            if(!Enum.TryParse(currentLocation,out ModuleName locationName))
            {
                return;
            }
            if (!ModuleHelper.IsBuffer(locationName))
            {
                return;
            }
            if (sequence.ModuleName == ModuleName.Transporter2)
            {
                TransporterAction transporterAction = sequence.Parameters as TransporterAction;
                if (transporterAction.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
                {
                    WaferHolderMoveItem waferHolderMoveItem = transporterAction.Parameter as WaferHolderMoveItem;
                    if (waferHolderMoveItem.SourceModule == ModuleName.Loader1 && waferHolderMoveItem.DestModuleType == ModuleType.Buffer)
                    {
                        WaferHolderInfo.IsToLoader = false;
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to false;");
                    }
                    else if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer && waferHolderMoveItem.SourceModuleType != ModuleType.Loader)
                    {
                        WaferHolderInfo.IsToLoader = true;
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true;");
                    }
                }
            }
        }
        /// <summary>
        /// 分析错误状态下的调度
        /// </summary>
        private void AnalyseSchedulerErrorState(SchedulerSequence sequence)
        {
            if (sequence.ModuleType == ModuleType.Prewet)
            {
                AnalyseSchedulerPrewetErrorState(sequence);
            }
            else if (sequence.ModuleType == ModuleType.Dryer)
            {
                AnalyseSchedulerDryerErrorState(sequence);
            }
            else if (sequence.ModuleType == ModuleType.Rinse)
            {
                AnalyseSchedulerRinseErrorState(sequence);
            }
            else if (sequence.ModuleType == ModuleType.Metal)
            {
                AnalyseSchedulerMetalErrorState(sequence);
            }
        }
        /// <summary>
        /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束
        /// </summary>
        /// <param name="sequence"></param>
        private bool BufferWaferHolderJudgeResource(SchedulerSequence sequence)
        {
            string currentLocation = WaferHolderInfo.CurrentLocation;
            if (Enum.TryParse(currentLocation, out ModuleName moduleName))
            {
                //当前WaferHolder处于Buffer中,当前步骤不是第一步,当前调度模块为transporter2
                if (ModuleHelper.IsBuffer(moduleName)&&_currentSequenceIndex!=0&&sequence.ModuleName==ModuleName.Transporter2)
                {
                    if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(WaferHolderInfo.SequenceRecipe, false))
                    {
                        for (int i = _currentSequenceIndex; i < _schedulerSequences.Count; i++)
                        {
                            SchedulerSequence item = _schedulerSequences[i];
                            item.State = RState.End;
                        }
                        _currentSequenceIndex = _schedulerSequences.Count - 1;
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} exist no avaible cell");
                        WaferHolderInfo.IsToLoader = true;
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true");
                        RemoveWaferHolderSRDScheduler();
                        UpdateWaferHolderMisProcessedStatus();
                        return false;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// 检验Prewet后面的Metal是否存在可用
        /// </summary>
        private void AnalysePrewetAfterMetalAvaible(SchedulerSequence schedulerSequence)
        {
            //获取可用的Metal以及Rinse            
            if (!CheckAfterMetalAvaible())
            {
                LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after prewet");
                SkipAfterMetal(schedulerSequence,true);
                RemoveWaferHolderSRDScheduler();
                UpdateWaferHolderMisProcessedStatus();
                //SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex];
                //if (nextSchedulerSequence.ModuleName != ModuleName.Transporter1)
                //{
                //    return;
                //}
                //WaferHolderMoveItem waferHolderMoveItem = nextSchedulerSequence.Parameters as WaferHolderMoveItem;
                //waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
                //waferHolderMoveItem.DestModule = ModuleName.Unknown;
            }
        }
        /// <summary>
        /// 检验Rinse后面的Metal是否存在可用
        /// </summary>
        /// <returns></returns>
        private void AnalyseRinseAfterMetalAvaible(SchedulerSequence schedulerSequence)
        {            
            //获取可用的Metal以及Rinse            
            if(!CheckAfterMetalAvaible())
            {
                LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after rinse");
                SkipAfterMetal(schedulerSequence,true);
                RemoveWaferHolderSRDScheduler();
                UpdateWaferHolderMisProcessedStatus();
            }
        }
        /// <summary>
        /// 检验后续Metal可用性
        /// </summary>
        /// <returns></returns>
        private bool CheckAfterMetalAvaible()
        {
            for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
            {
                SchedulerSequence sequence = _schedulerSequences[i];
                if (sequence.ModuleType != ModuleType.Metal)
                {
                    continue ;
                }
                if (sequence.Recipe == null || !(sequence.Recipe is DepRecipe))
                {
                    continue;
                }
                DepRecipe depRecipe = (DepRecipe)sequence.Recipe;
                bool result= SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, sequence.SequenceType,sequence.WaferSize);
                if (!result)
                {
                    return false;
                }
            }
            return true;
        }
        #region Analyse ErrorState Scheduler
        /// <summary>
        /// Prewet出错重新调度
        /// </summary>
        /// <param name="sequence"></param>
        private void AnalyseSchedulerPrewetErrorState(SchedulerSequence sequence)
        {
            SkipAfterSchedulerToDry(ModuleName.Transporter2);
            sequence.State = RState.End;
            sequence.EndTime = DateTime.Now;
            sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
            RemoveWaferHolderSRDScheduler();
            UpdateWaferHolderMisProcessedStatus();
            LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Prewet meet error,scheduler changed to transporter2");
        }
        /// <summary>
        /// 路过后面调度直接至Dryer
        /// </summary>
        private void SkipAfterSchedulerToDry(ModuleName transporterName)
        {
            for (int i = _currentSequenceIndex=1; i < _schedulerSequences.Count; i++)
            {
                SchedulerSequence item = _schedulerSequences[i];
                if (item.ModuleName != ModuleName.Transporter1)
                {
                    item.State = RState.End;
                    item.ProcessMilliSeconds = 0;
                }
                else
                {

                    if (item.Parameters is TransporterAction)
                    {
                        TransporterAction action= (TransporterAction)item.Parameters;
                        if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
                        {
                            WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
                            if (waferHolderMoveItem.DestModuleType == ModuleType.Dryer)
                            {
                                _currentSequenceIndex = i;
                                item.SchedulerModule = SchedulerManager.Instance.GetScheduler(transporterName);
                                waferHolderMoveItem.SourceModule = ModuleName.Prewet1;
                                waferHolderMoveItem.SourceModuleType = ModuleType.Prewet;
                                break;
                            }
                            else
                            {
                                item.State = RState.End;
                                item.ProcessMilliSeconds = 0;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer
        /// </summary>
        /// <param name="sequence"></param>
        private void AnalyseSchedulerDryerErrorState(SchedulerSequence sequence)
        {
            if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType,ModuleType.Dryer)!=ModuleName.Unknown)
            {
                sequence.State = RState.Init;
                SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
                preSchedulerSequence.State = RState.Init;
                preSchedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2);
                TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;
                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
                {
                    return;
                }
                WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
                waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
                waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
                waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
                waferHolderMoveItem.DestModule = ModuleName.Unknown;
                sequence.SchedulerModule = null;
                _currentSequenceIndex--;
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler changed to transporter2");
            }
            else
            {
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler has no avaible dryer");
            }
        }
        /// <summary>
        /// Rinse出错重新调度,回退至上一步调度
        /// </summary>
        /// <param name="sequence"></param>
        private void AnalyseSchedulerRinseErrorState(SchedulerSequence sequence)
        {
            ModuleName metalName = SchedulerSequenceManager.Instance.GetPreMetalModuleName(_currentSequenceIndex, _schedulerSequences);
            if (metalName == ModuleName.Unknown)
            {
                return;
            }
            if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType, ModuleType.Rinse,metalName) != ModuleName.Unknown)
            {
                sequence.State = RState.Init;
                SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
                preSchedulerSequence.State = RState.Init;
                TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;
                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
                {
                    return;
                }
                WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
                waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
                waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
                waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
                waferHolderMoveItem.DestModule = ModuleName.Unknown;
                sequence.SchedulerModule = null;
                _currentSequenceIndex--;
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,scheduler changed to transporter1");
            }
            else
            {
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,rescheduler has no avaible rinse");
            }
        }

        /// <summary>
        /// Metal出错重新调度,回退至上一步调度
        /// </summary>
        /// <param name="sequence"></param>
        private void AnalyseSchedulerMetalErrorState(SchedulerSequence sequence)
        {
            //当前步骤结束,WaferHolder状态
            UpdateWaferHolderErrorStatus();
            sequence.EndTime = DateTime.Now;
            sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
            sequence.State = RState.End;
            LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Metal meet error,rescheduler changed to next module");
            //跳过后面的metal
            SkipAfterMetal(sequence,false);
            //移除SRD调度
            RemoveWaferHolderSRDScheduler();
            _currentSequenceIndex++;
        }
        /// <summary>
        /// 跳过后面的Metal
        /// </summary>
        private void SkipAfterMetal(SchedulerSequence schedulerSequence,bool isSetLastSequenceSourceModule)
        {
            int startIndex = -1;
            int endIndex = -1;
            //从下一个Metal直到碰到Dryer
            for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
            {
                SchedulerSequence item = _schedulerSequences[i];
                if (item.ModuleType == ModuleType.Metal && startIndex == -1)
                {
                    startIndex = i;
                }
                if (item.ModuleType == ModuleType.Dryer)
                {
                    endIndex = i - 1;//Dryer前一步骤为Transporter,保留Dryer前面的transporter
                    break;
                }
            }
            //将后面的Metal的步骤直接跳过,包含gh g 后面的transporter
            if (startIndex != -1)
            {
                for (int i = startIndex - 1; i < endIndex; i++)
                {
                    SchedulerSequence item = _schedulerSequences[i];
                    item.State = RState.End;
                    LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} skip {i+1} sequence {item.ModuleType}");
                }
            }
            //是否设置最后调度的源模块
            if (isSetLastSequenceSourceModule)
            {
                SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex];
                if (lastSchedulerSequence.ModuleType == ModuleType.Transporter)
                {
                    TransporterAction action = lastSchedulerSequence.Parameters as TransporterAction;
                    if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
                    {
                        return;
                    }
                    WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
                    if (schedulerSequence.SchedulerModule != null)
                    {
                        waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName;
                        waferHolderMoveItem.SourceModuleType = schedulerSequence.ModuleType;
                    }
                }
            }
        }
        /// <summary>
        /// 移除SRD调度
        /// </summary>
        private void RemoveWaferHolderSRDScheduler()
        {
            WaferTask waferATask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferAId);
            if (waferATask != null)
            {
                waferATask.RemoveSrdScheduler();
            }
            WaferTask waferBTask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferBId);
            if (waferBTask != null)
            {
                waferBTask.RemoveSrdScheduler();
            }
        }

        #endregion

        /// <summary>
        /// 自动更新LoaderTransporter的工序
        /// </summary>
        private void AutoChangeLoaderTransporterScheduler()
        {
            if(_currentSequenceIndex>=_schedulerSequences.Count)
            {
                return;
            }
            if(_currentSequenceIndex+2>=_schedulerSequences.Count)
            {
                return;
            }
            SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];
            if (schedulerSequence == null)
            {
                return;
            }
            if(schedulerSequence.ModuleName==ModuleName.Transporter2)
            {
                if (schedulerSequence.Parameters == null || !(schedulerSequence.Parameters is TransporterAction))
                {
                    return;
                }
                TransporterAction action = (TransporterAction)schedulerSequence.Parameters;
                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
                {
                    return;
                }
                WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
                if(waferHolderMoveItem.DestModuleType!=ModuleType.Buffer)
                {
                    return;
                }
                SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex + 1];
                if(nextSchedulerSequence.ModuleName!=ModuleName.Transporter2)
                {
                    return;
                }
                if(nextSchedulerSequence.Parameters==null||!(nextSchedulerSequence.Parameters is TransporterAction))
                {
                    return;
                }
                TransporterAction nextAction = nextSchedulerSequence.Parameters as TransporterAction;
                if (nextAction.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
                {
                    return;
                }
                WaferHolderMoveItem nextWaferHolderMoveItem = (WaferHolderMoveItem)nextAction.Parameter;
                if(nextWaferHolderMoveItem.DestModule==ModuleName.Unknown)
                {
                    if (ProcessJobInfo != null && ProcessJobInfo.SequenceRecipe != null)
                    {
                        //后面不存在资源,搬运至Buffer中,而不是进后面cell
                        if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
                        {
                            return;
                        }
                    }
                    if (CheckBufferHasUnProcessedWaferHolder())
                    {
                        return;
                    }
                    //若Buffer后面的cell存在资源,则直接搬运至Cell中
                    ModuleName avaibleModuleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextWaferHolderMoveItem.DestModuleType,_sequenceType);
                    if(avaibleModuleName==ModuleName.Unknown)
                    {
                        return;
                    }
                    else
                    {
                        schedulerSequence.State = RState.End;
                        _currentSequenceIndex++;
                        nextWaferHolderMoveItem.DestModule = avaibleModuleName;
                        nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1;
                        nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader;

                        UpdateNextSequenceModule(_currentSequenceIndex + 1,avaibleModuleName);  
                    }
                }
                else if(nextWaferHolderMoveItem.DestModule==ModuleName.Loader1)
                {
                    LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
                    if(loaderEntity==null)
                    {
                        return;
                    }
                    if(loaderEntity.WaferHolderInfo!=null)
                    {
                        return;
                    }
                    if(loaderEntity.IsBusy)
                    {
                        return;
                    }
                    schedulerSequence.State = RState.End;
                    _currentSequenceIndex++;
                    nextWaferHolderMoveItem.SourceModule = waferHolderMoveItem.SourceModule;
                    nextWaferHolderMoveItem.SourceModuleType = waferHolderMoveItem.SourceModuleType;
                }
            }
        }
        /// <summary>
        /// 检验Buffer中是否存在未处理的WaferHolder
        /// </summary>
        /// <returns></returns>
        private bool CheckBufferHasUnProcessedWaferHolder()
        {
            List<string> bufferModules = BufferItemManager.Instance.InstalledModules;
            foreach (string module in bufferModules)
            {
                WaferHolderInfo item = WaferHolderManager.Instance.GetWaferHolder(module);
                if (item == null)
                {
                    continue;
                }
                if (string.IsNullOrEmpty(item.WaferAId))
                {
                    continue;
                }
                if (string.IsNullOrEmpty(item.WaferBId))
                {
                    continue;
                }
                WaferInfo waferA=WaferManager.Instance.GetWaferByWaferId(item.WaferAId);
                if (waferA == null)
                {
                    continue;
                }
                if (waferA.ProcessState == EnumWaferProcessStatus.Idle&&waferA.WaferType==WaferType.Production)
                {
                    return true;
                }
                WaferInfo waferB = WaferManager.Instance.GetWaferByWaferId(item.WaferBId);
                if(waferB == null)
                {
                    continue;
                }

                if (waferB.ProcessState == EnumWaferProcessStatus.Idle && waferB.WaferType == WaferType.Production)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 更新下一工序的调度模块
        /// </summary>
        /// <param name="sequenceIndex"></param>
        /// <param name="moduleName"></param>
        private void UpdateNextSequenceModule(int sequenceIndex,ModuleName moduleName)
        {
            if(sequenceIndex<_schedulerSequences.Count)
            {
                SchedulerSequence schedulerSequence = _schedulerSequences[sequenceIndex];
                if(schedulerSequence!=null&&schedulerSequence.SchedulerModule==null)
                {
                    schedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
                    schedulerSequence.ModuleName = moduleName;
                }
            }
        }

        /// <summary>
        /// 更新WaferHolder工序完成Wafer状态
        /// </summary>
        private void UpdateWaferHolderProcessComplete()
        {
            if (WaferHolderInfo.Status != WaferHolderStatus.Completed)
            {
                UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Completed);
                WaferHolderInfo.Status = WaferHolderStatus.Completed;
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
            }
            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
        }
        /// <summary>
        /// 更新WaferHolder工序正在加工
        /// </summary>
        private void UpdateWaferHolderProcessingStatus()
        {
            if (WaferHolderInfo.Status == WaferHolderStatus.Normal)
            {
                UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.InProcess);
                WaferHolderInfo.Status = WaferHolderStatus.Processing;
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
                MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
            }
        }
        /// <summary>
        /// 更新WaferHolder工序错误状态
        /// </summary>
        /// <param name="sequence"></param>
        private void UpdateWaferHolderErrorStatus()
        {
            UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed);
            WaferHolderInfo.Status = WaferHolderStatus.Failed;
            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
        }

        /// <summary>
        /// 更新WaferHolder工序MisProcessed状态
        /// </summary>
        /// <param name="sequence"></param>
        private void UpdateWaferHolderMisProcessedStatus()
        {
            UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed);
            WaferHolderInfo.Status = WaferHolderStatus.MisProcessed;
            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
        }

        /// <summary>
        /// 更新WaferHolder处理状态
        /// </summary>
        /// <param name="sequence"></param>
        /// <param name="processStatus"></param>
        private void UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus processStatus)
        {
            if (Enum.TryParse(WaferHolderInfo.CurrentLocation, out ModuleName moduleName))
            {
                if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
                {
                    WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
                    if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
                    {
                        WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 0, processStatus);
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
                    }
                }
                if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
                {
                    WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
                    if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
                    {
                        WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 1, processStatus);
                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
                    }
                }
            }
        }
        /// <summary>
        /// 检验前置条件
        /// </summary>
        /// <returns></returns>
        private bool CheckStartCondition()
        {
            LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
           
            if (loaderEntity.WaferHolderInfo != null)
            {
                return false;
            }
            //if (ProcessJobInfo != null)
            //{
            //    if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
            //    {
            //        _currentSequenceIndex = _schedulerSequences.Count;
            //        LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"WaferHolder {WaferHolderInfo.Id} start scheduler meet no avaible cell");
            //        return false;
            //    }
            //}
            return true;
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _schedulerSequences.Clear();
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            _pausedIndex = _currentSequenceIndex;
        }
        /// <summary>
        /// 恢复
        /// </summary>
        public void Resume()
        {
            _pausedIndex = -1;
        }
        /// <summary>
        /// 获取当前调度阶段
        /// </summary>
        /// <returns></returns>
        public SchedulerSequence GetCurrentSchedulerSequence()
        {
            return GetSchedulerSequenceByIndex(_currentSequenceIndex);
        }
        /// <summary>
        /// 获取前一个调度阶段
        /// </summary>
        /// <returns></returns>
        public SchedulerSequence GetPreSchedulerSequence()
        {
            return GetSchedulerSequenceByIndex(_currentSequenceIndex-1);
        }
        /// <summary>
        /// 根据索引获取调度阶段对象
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private SchedulerSequence GetSchedulerSequenceByIndex(int index)
        {
            if (index == -1 || index >= _schedulerSequences.Count)
            {
                return null;
            }
            return _schedulerSequences[index];
        }
        /// <summary>
        /// 是否调度完成Loader调度
        /// </summary>
        /// <returns></returns>
        public bool IsNotPassLoader()
        {
            return _currentSequenceIndex <= 1;
        }
    }
}