using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.LinMot;
using CyberX8_RT.Devices.Prewet;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
namespace CyberX8_RT.Modules.Prewet
{
    public class PrewetProcessRoutine : RoutineBase, IRoutine
    {       
        private enum ProcessStep
        {
            Process_Start,
            Process_StartScanning,
            Process_WaitPumpOnEnd,
            Process_WaitFirstScanComplete,
            Process_WaitScanComplete,
            Process_Complete,
            End
        }
        #region 内部变量
        /// 
        /// prewet设备
        /// 
        private PrewetDevice _prewetDevice;
        /// 
        /// linmot axis
        /// 
        private LinMotAxis _linMotAxis;
        /// 
        /// Prewet recipe
        /// 
        private PwtRecipe _recipe;    
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PrewetProcessRoutine(string module, LinMotAxis linMotAxis) : base(module)
        {
            this._linMotAxis = linMotAxis;
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            _linMotAxis.StopOperation("", null);
            _prewetDevice.PumpValveClose();
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {         
            Runner.Run(ProcessStep.Process_Start, NullFun, _delay_1ms)
                .Run(ProcessStep.Process_StartScanning, ProcessStartScan, _delay_1ms)
                .WaitWithStopCondition(ProcessStep.Process_WaitPumpOnEnd, WaitProcessEndStatus, CheckProcessFailedStatus, _delay_60s)
                .Run(ProcessStep.Process_WaitFirstScanComplete, StartScan, _delay_1ms)
                .WaitWithStopCondition(ProcessStep.Process_WaitScanComplete, WaitScanComplete, CheckScanStopEnd)
                .Run(ProcessStep.Process_Complete, ProcessComplete, CheckPumpValveClose,_delay_3s)
                .End(ProcessStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        
        /// 
        /// Process Start Scan
        /// 
        /// 
        private bool ProcessStartScan()
        {
            bool result = _linMotAxis.ResetOperation("", false);
            if (!result)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "reset linmot error");
                return false;
            }
            //_prewetDevice.PrewetPumpData.PumpSpeedAuto = true;
            //更新Pump status状态
            //string statusContent = _prewetDevice.PrewetPumpData.PumpStatus ? "On" : "Off";
            //_prewetDevice.PrewetPumpData.PumpModel = "Auto";
            //_prewetDevice.PrewetPumpData.PumpStatusContent = $"{_prewetDevice.PrewetPumpData.PumpModel}: {statusContent}";
            //result = _prewetDevice.PumpSpeed();
            //if (!result)
            //{
            //    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump speed error");
            //    return false;
            //}
            bool pumpEnableResult = _prewetDevice.PumpValveOpen();
            if (!pumpEnableResult)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump valve open error");
                return false;
            }
            return true;
        }
        /// 
        /// 等待结束状态
        /// 
        /// 
        private bool WaitProcessEndStatus()
        {
            if (_linMotAxis.Status == RState.End)
            {
                return true;
            }
            return false;
        }
        /// 
        /// 检验错误状态
        /// 
        /// 
        private bool CheckProcessFailedStatus()
        {
            //if (_prewetDevice.Status == RState.Failed)
            //{
            //    LOG.WriteLog(eEvent.ERR_PREWET, Module, "prewet device status is error");
            //    return true;
            //}
            if (_linMotAxis.Status == RState.Failed)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "linmot status is error");
                return true;
            }
            return false;
        }
        /// 
        /// 自动调速
        /// 
        private bool StartAdjustSpeed()
        {
            //_prewetDevice.IsStartAutoSpeed = true;
            return true;
        }
        /// 
        /// 开始Scan
        /// 
        /// 
        /// 
        private bool StartScan()
        {
            if (!_linMotAxis.IsHomed)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "limot is not ready");
                return false;
            }
            //if (!_prewetDevice.PrewetPumpData.PumpStatus)
            //{
            //    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump status if off");
            //    return false;
            //}
            bool result = _linMotAxis.StartPosition("", new object[] { _recipe.NumberOfScans });
            if (!result)
            {
                _prewetDevice.PumpValveClose();
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "linmot start scan error");
                return false;
            }
            return result;
        }
        /// 
        /// 等待Scan结束
        /// 
        /// 
        /// 
        private bool WaitScanComplete()
        {
            //linmot完成一次scan
            if (_linMotAxis.Status == RState.End)
            {
                return true;
            }
            
            return false;
        }
        /// 
        /// 检验Prewet停止状态
        /// 
        /// 
        private bool CheckScanStopEnd()
        {
            if (_linMotAxis.Status == RState.Failed||_linMotAxis.Status==RState.Timeout)
            {
                _prewetDevice.PumpValveClose();
                return true;
            }
            //Pressure
            if (_prewetDevice.PrewetPumpData.PumpPressureData.IsError)
            {
                _linMotAxis.StopOperation("",null);
                _prewetDevice.PumpValveClose();
                LOG.WriteLog(eEvent.ERR_PREWET, Module, $"Pump pressure {_prewetDevice.PrewetPumpData.PumpPressureData.Value} is in error");
                return true;
            }
            else if (_prewetDevice.PrewetPumpData.PumpPressureData.IsWarning)
            {
                string str = $"Pump pressure {_prewetDevice.PrewetPumpData.PumpPressureData.Value} is in warning";
                if (AlarmListManager.Instance.AddWarn(Module, "Pump Pressure", str))
                {
                    LOG.WriteLog(eEvent.WARN_PREWET, Module, str);
                }
            }
            //Flow
            if (_prewetDevice.PrewetPumpData.PumpFlowData.IsError)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, $"Pump flow {_prewetDevice.PrewetPumpData.PumpFlowData.Value} is in error");
                _linMotAxis.StopOperation("", null);
                _prewetDevice.PumpValveClose();
                return true;
            }
            else if (_prewetDevice.PrewetPumpData.PumpFlowData.IsWarning)
            {
                string str = $"Pump flow {_prewetDevice.PrewetPumpData.PumpFlowData.Value}  is in warning";
                if (AlarmListManager.Instance.AddWarn(Module, "Pump Flow", str))
                {
                    LOG.WriteLog(eEvent.WARN_PREWET, Module, str);
                }
            }
            return false;
        }
        /// 
        /// Process scan完成
        /// 
        /// 
        /// 
        private bool ProcessComplete()
        {
            bool result = _prewetDevice.PumpValveClose();
            if (!result)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump valve close error");
                return false;
            }
            //result = _prewetDevice.PumpDisable();
            //if (!result)
            //{
            //    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump enable close");
            //    return false;
            //}
            //bool result = _prewetDevice.PumpDisableOperation("pump disable",null);
            return true;
        }
        private bool CheckPumpValveClose()
        {
            bool result = !_prewetDevice.PrewetPumpData.PumpValve;
            return result;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            //清除lotTrack数据
            _prewetDevice = DEVICE.GetDevice(Module);
            _recipe = objs[0] as PwtRecipe;
            if (_recipe == null)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "recipe is null");
                return RState.Failed;
            }
       
            return Runner.Start(Module, "Start Process Recipe");
        }
    }
}