using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.TwinCat;
using MECF.Framework.Common.IOCore;
namespace CyberX8_RT.Devices.Safety
{
    public class SafetyResetRoutine : RoutineBase, IRoutine
    {
        private enum SafetyResetStep
        {
            SrdArm,
            RunStop,
            ErrAck,
            LockProcessDoors,
            LockBufferDoors,
            LockLoaderDoors,
            TxSto1EstopRestart,
            TxEstopDelay,
            TxStoMonRestart,
            TxMonDelay,
            TxSto2EstopRestart,            
            LdrPufSto1EstopRestart,
            LdrPufEstopDelay,
            LdrPufStoMonRestart,
            LdrPufMonDelay,
            LdrPufSto2EstopRestart,
            SrdStoEstopRestart,
            PumpStoEstopRestart,
            PumpEstopDelay,
            FluidEstopRestart,
            FluidEstopDelay,
            SlsRestart,
            End
        }
        #region 常量
        private const string RUNSTOP = "RunStop";
        #endregion
        #region 内部变量
        private SafetyArmResetRoutine _srdArmResetRoutine;
        private SafetyToggleRoutine _errAckToggleRoutine;
        private SafetyToggleRoutine _txSto1EstopRestartRoutine;
        private SafetyToggleRoutine _txStoMonRestartRoutine;
        private SafetyToggleRoutine _txSto2EstopRestartRoutine;
        private SafetyToggleRoutine _ldrPufSto1EstopRestart;
        private SafetyToggleRoutine _ldrPufStoMonRestart;
        private SafetyToggleRoutine _ldrPufSto2EstopRestart;
        private SafetyToggleRoutine _srdStoEstopRestart;
        private SafetyToggleRoutine _pumpStoEstopRestart;
        private SafetyToggleRoutine _fluidEstopRestart;
        private SafetyToggleRoutine _slsRestart;
        private SafetyDevice _device;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SafetyResetRoutine(string module) : base(module)
        {
            _errAckToggleRoutine = new SafetyToggleRoutine(module);
            _txSto1EstopRestartRoutine = new SafetyToggleRoutine(module);
            _txStoMonRestartRoutine=new SafetyToggleRoutine(module);
            _txSto2EstopRestartRoutine=new SafetyToggleRoutine(module);
            _ldrPufSto1EstopRestart=new SafetyToggleRoutine(module);
            _ldrPufStoMonRestart=new SafetyToggleRoutine(module);
            _ldrPufSto2EstopRestart=new SafetyToggleRoutine(module);
            _srdStoEstopRestart=new SafetyToggleRoutine(module);
            _pumpStoEstopRestart = new SafetyToggleRoutine(module);
            _fluidEstopRestart=new SafetyToggleRoutine(module);
            _slsRestart=new SafetyToggleRoutine(module);
            _srdArmResetRoutine=new SafetyArmResetRoutine(module);
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manaul abort safety reset");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(SafetyResetStep.SrdArm, () => { return _srdArmResetRoutine.Start("SRDArmReset") == RState.Running; },
                () => { return CheckRoutineStatus(_srdArmResetRoutine); }, _delay_1s)
                .Run(SafetyResetStep.RunStop, RunStop, _delay_1ms)
                .Run(SafetyResetStep.ErrAck, () => { return _errAckToggleRoutine.Start("ErrAck") == RState.Running; },
                () => { return CheckRoutineStatus(_errAckToggleRoutine); }, _delay_1s)
                .Run(SafetyResetStep.LockProcessDoors, () => { return _device.LockProcessDoor(); }, _delay_1ms)
                .Run(SafetyResetStep.LockBufferDoors, () => { return _device.LockBufferDoor(); }, _delay_1ms)
                .Run(SafetyResetStep.LockLoaderDoors, () => { return _device.LockLoaderDoor(); }, _delay_1ms)
                .Run(SafetyResetStep.TxSto1EstopRestart, () => { return _txSto1EstopRestartRoutine.Start("TxSto1EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_txSto1EstopRestartRoutine); }, _delay_1s)
                .Delay(SafetyResetStep.TxEstopDelay,100)//100 delay
                .Run(SafetyResetStep.TxStoMonRestart, () => { return _txStoMonRestartRoutine.Start("TxStoMonRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_txStoMonRestartRoutine); }, _delay_1s)
                .Delay(SafetyResetStep.TxMonDelay, 100)//100 delay
                .Run(SafetyResetStep.TxSto2EstopRestart, () => { return _txSto2EstopRestartRoutine.Start("TxSto2EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_txSto2EstopRestartRoutine); }, _delay_1s)
                .Run(SafetyResetStep.LdrPufSto1EstopRestart, () => { return _ldrPufSto1EstopRestart.Start("LdrPufSto1EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_ldrPufSto1EstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.LdrPufEstopDelay,_delay_1s)//1000 delay
                .Run(SafetyResetStep.LdrPufStoMonRestart, () => { return _ldrPufStoMonRestart.Start("LdrPufStoMonRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_ldrPufStoMonRestart); }, _delay_1s)
                .Delay(SafetyResetStep.LdrPufMonDelay, 100)//100 delay
                .Run(SafetyResetStep.LdrPufSto2EstopRestart, () => { return _ldrPufSto2EstopRestart.Start("LdrPufSto2EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_ldrPufSto2EstopRestart); }, _delay_1s)
                .Run(SafetyResetStep.SrdStoEstopRestart, () => { return _srdStoEstopRestart.Start("SrdStoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_srdStoEstopRestart); }, _delay_1s)
                .Run(SafetyResetStep.PumpStoEstopRestart, () => { return _pumpStoEstopRestart.Start("PumpStoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_pumpStoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.PumpEstopDelay,100)//100 delay
                .Run(SafetyResetStep.FluidEstopRestart, () => { return _fluidEstopRestart.Start("FluidEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_fluidEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.FluidEstopDelay,_delay_1s)
                .Run(SafetyResetStep.SlsRestart, () => { return _slsRestart.Start("SlsRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_slsRestart); }, _delay_1s)
                .End(SafetyResetStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 
        /// 
        /// 
        private bool RunStop()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{RUNSTOP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// 检验是否完成
        /// 
        /// 
        /// 
        private bool CheckRoutineStatus (IRoutine routine)
        {
            RState rsState = routine.Monitor();
            return rsState == RState.End;
        }
        /// 
        /// 检验Process door locked状态
        /// 
        /// 
        private bool CheckProcessDoorLocked()
        {
            return _device.SafetyData.ProcessDoor1Locked && _device.SafetyData.ProcessDoor2Locked && _device.SafetyData.ProcessDoor3Locked &&
                    _device.SafetyData.ProcessDoor4Locked;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _device = DEVICE.GetDevice("Safety");
            return Runner.Start(Module, "Start Reset safety");
        }
    }
}