using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.Rinse;
using System;
using System.Collections.Generic;
using MECF.Framework.Common.Utilities;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.CommonData.Rinse;
using CyberX8_RT.Devices.Resistivity;
using MECF.Framework.Common.CommonData;
using Aitex.Core.Util;
using CyberX8_RT.Devices.Facilities;
using Aitex.Core.RT.SCCore;
namespace CyberX8_RT.Modules.Rinse
{
    sealed class RinseCycleManualProcessRecipeRoutine : RoutineBase,IRoutine
    {
        private const int LOTTRACK_TIME = 1000;
        private const string DI_WATER_PRESSURE_VALUE = "DiWaterPressure";
        private enum CycleManualRunRecipeStep
        {
            LoopStart,
            
            LoopRunFirstStep,
            LoopWaitRunFirstStepProcess,
            LoopFirstStepDelay,
           
            LoopRunSecondStep,
            LoopWaitRunSecondStepProcess,
            LoopSecondStepDelay,
            
            LoopRunThirdStep,
            LoopWaitRunThirdStepProcess,
            LoopThirdStepDelay,
            
            LoopEnd,
            ProcessComplete
        }
        #region 内部变量
        private RinseFirstStepRoutine _rinseFirstStepRoutine;
        private RinseSecondStepRoutine _rinseSecondStepRoutine;
        private RinseThirdStepRoutine _rinseThirdStepRoutine;
        private int _cycle = 0;
        private int _achievedCycle;
        private object[] param;
        /// 
        /// 设备对象
        /// 
        private RinseDevice _device;
        /// 
        /// Recipe
        /// 
        private QdrRecipe _recipe;
        /// 
        /// 当前执行到哪一步的显示
        /// 
        private string _currentStateMachine;
        /// 
        /// lock track time
        /// 
        private DateTime _lotTackTime = DateTime.Now;
        /// 
        /// LotTrack数据
        /// 
        private List _datas = new List();
        /// 
        /// LotTrack文件头数据
        /// 
        private LotTrackFileHeaderCommonData _header = new LotTrackFileHeaderCommonData();       
        /// 
        /// Facilities
        /// 
        private SystemFacilities _facilities;
        #endregion
        #region 属性
        /// 
        /// LotTrack数据
        /// 
        public List RinseLotTrackDatas { get { return _datas; } }
        /// 
        /// LotTrack文件头数据
        /// 
        public LotTrackFileHeaderCommonData RinseLotTrackHeaderDatas { get { return _header; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public RinseCycleManualProcessRecipeRoutine(string module) : base(module)
        {
            _rinseFirstStepRoutine = new RinseFirstStepRoutine(module);
            _rinseSecondStepRoutine =  new RinseSecondStepRoutine(module);
            _rinseThirdStepRoutine = new RinseThirdStepRoutine(module);
        }
        /// 
        /// Start  参数包括cycle和recipe
        /// 
        public RState Start(params object[] objs)
        {
            //清除lotTrack数据
            _datas.Clear();
            _device = DEVICE.GetDevice(Module);
            _recipe = objs[0] as QdrRecipe;
            if (_recipe == null)
            {
                NotifyError(eEvent.ERR_RINSE, "recipe is null",-1);
                return RState.Failed;
            }
            _cycle = (int)objs[1];
            _achievedCycle = 0;
            param = objs;
            if (SC.ContainsItem("System.ToolID")) _header.ToolID = SC.GetStringValue("System.ToolID");
            _header.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            _header.Recipe = $"{_recipe.Ppid}.qdr.rcp";
            //lotTract记录SequenceRecipe
            RinseEntity rinseEntity = Singleton.Instance.GetModule(Module);
            if (rinseEntity.WaferHolderInfo != null &&  rinseEntity.WaferHolderInfo.SequenceRecipe != null &&   !String.IsNullOrEmpty(rinseEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString()))
            {
                _header.SequenceRecipe = rinseEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString();
                _header.ProcessTransferList = new List();
                _header.ProcessTransferList.AddRange(rinseEntity.WaferHolderInfo.SchedulerModules);
                rinseEntity.WaferHolderInfo.SchedulerModules.Clear();
            }
           
            _facilities = DEVICE.GetDevice("System.Facilities");
            if(_facilities == null)
            {                
                LOG.WriteLog(eEvent.ERR_RINSE, Module, "Facility is null");
                return RState.Failed;               
            }
            
            _lotTackTime = DateTime.Now;
            return Runner.Start(Module, "Start cycle ManualRunRecipe");
        }
        /// 
        /// Monitor
        /// 
        /// 
        public RState Monitor()
        {
            _currentStateMachine = Runner.CurrentStep.ToString();
            _device.UpdateStatus(_currentStateMachine);
            LottrackRecord();
            Runner.LoopStart(CycleManualRunRecipeStep.LoopStart, "Loop Start ManualRunRecipe", _cycle, NullFun, _delay_1ms)
                
                .LoopRun(CycleManualRunRecipeStep.LoopRunFirstStep, startFirstRoutine, _delay_1ms)
                .LoopRunWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunFirstStepProcess, () => CommonFunction.CheckRoutineEndState(_rinseFirstStepRoutine), 
                    () => { return CheckRoutineStopStatus(_rinseFirstStepRoutine, _rinseFirstStepRoutine.ErrorMsg, 0); })
                .LoopDelay(CycleManualRunRecipeStep.LoopFirstStepDelay, _delay_1ms)                
                .LoopRun(CycleManualRunRecipeStep.LoopRunSecondStep, startSecondRoutine, _delay_1ms)
                .LoopRunWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunSecondStepProcess, () => CommonFunction.CheckRoutineEndState(_rinseSecondStepRoutine),
                    () => { return CheckRoutineStopStatus(_rinseSecondStepRoutine, _rinseSecondStepRoutine.ErrorMsg, 0); })
                .LoopDelay(CycleManualRunRecipeStep.LoopSecondStepDelay, _delay_1ms)
                
                .LoopRunIf(CycleManualRunRecipeStep.LoopRunThirdStep, _recipe.FinalRinseDry == true, startThirdRoutine, _delay_1ms)
                .LoopRunIfWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunThirdStepProcess, _recipe.FinalRinseDry == true, () => CommonFunction.CheckRoutineEndState(_rinseThirdStepRoutine), 
                    () => { return CheckRoutineStopStatus(_rinseThirdStepRoutine, _rinseThirdStepRoutine.ErrorMsg, 0); })
                .LoopRunIf(CycleManualRunRecipeStep.LoopThirdStepDelay, _recipe.FinalRinseDry == true, NullFun, _delay_1ms)
                
                .LoopEnd(CycleManualRunRecipeStep.LoopEnd, AchievedCycleCount, _delay_1ms)
                .End(CycleManualRunRecipeStep.ProcessComplete, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 启动第一阶段Rinse
        /// 
        /// 
        private bool startFirstRoutine()
        {
            bool result = _rinseFirstStepRoutine.Start(param) == RState.Running;
            if (!result)
            {
                AddLotTrackData();
                NotifyError(eEvent.ERR_RINSE, _rinseFirstStepRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// 启动第二阶段Rinse
        /// 
        /// 
        private bool startSecondRoutine()
        {
            bool result = _rinseSecondStepRoutine.Start(param) == RState.Running;
            if (!result)
            {
                AddLotTrackData();
                NotifyError(eEvent.ERR_RINSE, _rinseSecondStepRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// 启动第三阶段Rinse
        /// 
        /// 
        private bool startThirdRoutine()
        {
            bool result = _rinseThirdStepRoutine.Start(param) == RState.Running;
            if (!result)
            {
                AddLotTrackData();
                NotifyError(eEvent.ERR_RINSE, _rinseThirdStepRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// 检验Routine停止状态
        /// 
        /// 
        /// 
        /// 
        /// 
        private bool CheckRoutineStopStatus(IRoutine routine,string error,int index)
        {
            bool result=CommonFunction.CheckRoutineStopState(routine);
            if (result)
            {
                AddLotTrackData();
                NotifyError(eEvent.ERR_RINSE, error, 0);
            }
            return result;
        }
        /// 
        /// 记录Lottrack
        /// 
        private void LottrackRecord()
        {
            //记录Lottrack
            if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
            {
                AddLotTrackData();
                _lotTackTime = DateTime.Now;
            }
        }
       
        /// 
        /// 获取Lot Track数据
        /// 
        /// 
        private void AddLotTrackData()
        {
            RinseLotTrackData data = new RinseLotTrackData();
            data.TimeStamp = DateTime.Now;
            data.StateMachine = _device.CurrentStateMachine;
            data.WaterLevel = _device.RinseData.WaterLevel;
            data.DIFillEnabled = _device.RinseData.FillValve;
            data.DumpEnabled = _device.RinseData.DrainValve;
            data.WaterPressure = _facilities.GetCommonLimitDataByName(DI_WATER_PRESSURE_VALUE).Value;
            ResistivityController resistivityController = DEVICE.GetDevice(_device.RinseItem.ResistivityID);
            if (resistivityController != null)
            {
                try
                {
                    data.Resistivity = double.Parse(resistivityController.ResisitivityValue.Trim());
                }
                catch
                {
                    data.Resistivity = 0;
                }
            }
            _datas.Add(data);
        }
        /// 
        /// 统计完成的Cycle次数
        /// 
        /// 
        private bool AchievedCycleCount()
        {
            _achievedCycle += 1;
            return true;
        }
        /// 
        /// 释放定时器
        /// 
        /// 
        private bool DisposeTimer()
        {
            return true;
        }
        /// 
        /// 获取已经完成的Cycle次数
        /// 
        /// 
        public int GetAchievedCycle()
        {
            return _achievedCycle;
        }
        
        /// 
        /// Abort
        /// 
        public void Abort()
        {
            if (_device != null)
            {
                _device.N2ValveOff();
                _device.FillValveOff();
            }
            Runner.Stop("Cycle ManualRunRecipe Abort");
        }
        /// 
        /// 重试
        /// 
        /// 
        public RState Retry(int step)
        {
            if (_recipe == null)
            {
                NotifyError(eEvent.ERR_RINSE, "recipe is null",-1);
                return RState.Failed;
            }
            List preStepIds = new List();
            return Runner.Retry(CycleManualRunRecipeStep.LoopStart, preStepIds, Module, "Runrecipe Retry");
        }
    }
}