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.CommonData.Prewet;
using MECF.Framework.Common.Routine;
using System;
using System.Collections.Generic;
namespace CyberX8_RT.Modules.Prewet
{
    public class PrewetKeepWetRoutine : RoutineBase, IRoutine
    {
        private const int LOTTRACK_TIME = 1000;
        private enum KeepwetStep
        {
            Idle_KeepwetPrepare,
            Idle_KeepwetPrepareWait,
            Idle_KeepWetStart,
            Idle_KeepWetScan,
            Idle_KeepWetPause,
            End
        }
        #region 内部变量
        /// 
        /// prewet设备
        /// 
        private PrewetDevice _prewetDevice;
        /// 
        /// linmot axis
        /// 
        private LinMotAxis _linMotAxis;
        /// 
        /// Lottrack time
        /// 
        private DateTime _lotTackTime = DateTime.Now;
        /// 
        /// LotTrack数据
        /// 
        private List _datas = new List();
        /// 
        /// LotTrack数据
        /// 
        public List PrewetLotTrackDatas { get { return _datas; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PrewetKeepWetRoutine(string module,LinMotAxis linMotAxis) : base(module)
        {
            _linMotAxis= linMotAxis;
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            _linMotAxis.StopOperation("", null);
            if (_prewetDevice != null)
            {
                _prewetDevice.PumpValveClose();
            }
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            LottrackRecord();
            Runner.Run(KeepwetStep.Idle_KeepwetPrepare, ResetLinmot, _delay_1ms)
                .WaitWithStopCondition(KeepwetStep.Idle_KeepwetPrepareWait, CheckResetLinmotEndStatus, CheckResetLinmotStopStatus)
                .Run(KeepwetStep.Idle_KeepWetStart, ExecuteWetScan, _delay_1s)
                .WaitWithStopCondition(KeepwetStep.Idle_KeepWetScan,CheckLinmotScanEndStatus,CheckLinmotScanStopStatus)
                .Run(KeepwetStep.Idle_KeepWetPause, KeepWetComplete, _delay_1ms)
                .End(KeepwetStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// Reset Linmot
        /// 
        /// 
        /// 
        private bool ResetLinmot()
        {
            bool result = _linMotAxis.ResetOperation("", false);
            if (!result)
            {
                return false;
            }
            return true;
        }
        /// 
        /// 检验Reset Linmot状态
        /// 
        /// 
        /// 
        private bool CheckResetLinmotEndStatus()
        {
            return _linMotAxis.Status == RState.End;
        }
        /// 
        /// 检验Reset Linmot停止状态
        /// 
        /// 
        private bool CheckResetLinmotStopStatus()
        {
            if(_linMotAxis.Status == RState.Failed || _linMotAxis.Status == RState.Timeout)
            {
                AddLotTrackData();
                return true;
            }
            return false;
        }
        /// 
        /// execute Keep Wet Scan
        /// 
        /// 
        /// 
        private bool ExecuteWetScan()
        {
            bool pumpValveResult = _prewetDevice.PumpValveOpen();
            if (!pumpValveResult)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump valve open error");
                return false;
            }
            //bool pumpEnableResult = _prewetDevice.PumpEnableOperation("", null);
            //bool pumpEnableResult = _prewetDevice.PumpEnable();
            //if (!pumpEnableResult)
            //{
            //    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump enable error");
            //    return false;
            //}
            bool result = _linMotAxis.StartPosition("", new object[] { 1 });
            if (!result)
            {
                return false;
            }
            return true;
        }
        /// 
        /// 检验Linomot扫描结束状态
        /// 
        /// 
        private bool CheckLinmotScanEndStatus()
        {
            return _linMotAxis.Status == RState.End;
        }
        /// 
        /// 检验Linmot Scan停止状态
        /// 
        /// 
        private bool CheckLinmotScanStopStatus()
        {
            bool result=_linMotAxis.Status==RState.Failed||_linMotAxis.Status==RState.Timeout;
            if(!result)
            {
                //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;
            }
            else
            {
                AddLotTrackData();
                _prewetDevice.PumpValveClose();
                return true;
            }
        }
        /// 
        /// Wait execute WetScan
        /// 
        /// 
        /// 
        private bool WaitExecuteWetScan(object param)
        {
            
            //linmot完成一次scan
            if (_linMotAxis.Status == RState.End)
            {
                return true;
            }
            return false;
        }
        /// 
        /// Keep wet scan完成
        /// 
        /// 
        /// 
        private bool KeepWetComplete()
        {
            bool result = _prewetDevice.PumpValveClose();
            if (!result)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump valve close error");
                return false;
            }
            result = _linMotAxis.SwitchOff();
            if (!result)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "linmot disable error");
                return false;
            }
            return true;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _prewetDevice = DEVICE.GetDevice(Module);
            _datas.Clear();
            _lotTackTime = DateTime.Now;
            return Runner.Start(Module, "Start Keepwet");
        }
        /// 
        /// 记录Lottrack
        /// 
        private void LottrackRecord()
        {
            //记录Lottrack
            if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
            {
                AddLotTrackData();
                _lotTackTime = DateTime.Now;
            }
        }
        /// 
        /// 获取Lot Track数据
        /// 
        /// 
        private void AddLotTrackData()
        {
            PrewetLotTrackData data = new PrewetLotTrackData();
            data.TimeStamp = DateTime.Now;
            data.StateMachine = Runner.CurrentStep.ToString();
            data.Pressure = _prewetDevice.PrewetPumpData.PumpPressureData.Value;
            data.Flow = _prewetDevice.PrewetPumpData.PumpFlowData.Value;
            data.PumpMode = _prewetDevice.PrewetPumpData.PumpModel;
            data.PressureTarget = _prewetDevice.PrewetPumpData.PressureTarget;
            data.CurrentScan = _linMotAxis.ScanCount;
            data.ScanOn = _linMotAxis.IsMotorOn;
            data.ValveState = _prewetDevice.PrewetPumpData.PumpValve;
            data.PumpSpeed = _prewetDevice.LastPumpSpeed;
            data.PumpControlCurrent = _prewetDevice.PrewetPumpData.PumpCurrent;
            _datas.Add(data);
        }
    }
}