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.Routine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static CyberX8_RT.Modules.Prewet.PrewetKeepWetStateMachine;
namespace CyberX8_RT.Modules.Prewet
{
    public class PrewetKeepWetRoutine : RoutineBase, IRoutine
    {
        private enum KeepwetStep
        {
            Idle_KeepwetPrepare,
            Idle_KeepwetPrepareWait,
            Idle_KeepWetStart,
            Idle_KeepWetScan,
            Idle_KeepWetPause,
            End
        }
        #region 内部变量
        /// 
        /// prewet设备
        /// 
        private PrewetDevice _prewetDevice;
        /// 
        /// linmot axis
        /// 
        private LinMotAxis _linMotAxis;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PrewetKeepWetRoutine(string module,LinMotAxis linMotAxis) : base(module)
        {
            _linMotAxis= linMotAxis;
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            _linMotAxis.StopOperation("", null);
            if (_prewetDevice != null)
            {
                _prewetDevice.PumpDisableOperation("prewetPump Disable",null);
            }
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(KeepwetStep.Idle_KeepwetPrepare, ResetLinmot, _delay_1ms)
                .WaitWithStopCondition(KeepwetStep.Idle_KeepwetPrepareWait, CheckResetLinmotEndStatus, CheckResetLinmotStopStatus)
                .Run(KeepwetStep.Idle_KeepWetStart, ExecuteWetScan, _delay_1ms)
                .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()
        {
            return _linMotAxis.Status == RState.Failed || _linMotAxis.Status == RState.Timeout;
        }
        /// 
        /// 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)
            {
                string strFlow = $"pump flow status is {_prewetDevice.PrewetPumpData.PumpFlowData.Value} in warning";
                if (AlarmListManager.Instance.AddWarn(Module, "Pump Flow", strFlow))
                {
                    LOG.WriteLog(eEvent.WARN_PREWET, Module, strFlow);
                }
                if (_prewetDevice.PrewetPumpData.PumpFlowData.IsError)
                {
                    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump flow status is in error");
                    return true;
                }
                string strPressure = $"pump pressure status is {_prewetDevice.PrewetPumpData.PumpPressureData.Value} in warning";
                if (AlarmListManager.Instance.AddWarn(Module, "Pump Pressure", strPressure))
                {
                    LOG.WriteLog(eEvent.WARN_PREWET, Module, strPressure);
                }
                if (_prewetDevice.PrewetPumpData.PumpPressureData.IsError)
                {
                    LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump pressure status is in error");
                    return true;
                }
                return false;
            }
            else
            {
                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.PumpDisableOperation("pump disable",null);
            if (!result)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "pump disable 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);
            return Runner.Start(Module, "Start Keepwet");
        }
    }
}