using System.Diagnostics;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
using SicModules.Devices;
using SicModules.LLs;

namespace SicModules.TMs.Routines
{
    public class TMPurgeRoutine  : TMBaseRoutine
    {
        enum RoutineStep
        {
            StartLoop,
            LoopPump,
            LoopVent,
            StopLoop,

            //Pump
            CloseV77,
            CloseV80,
            SlowPump,
            FastPump,
            VaccumDelay,
            CloseValves,
            CLoseSlowValue,

            //Vent
            CloseV81,
            CloseV82,
            SetMFC1,
            SetMFC2,
            OpenSlowVent,
            OpenFastVent,
            OpenVent,
            TimeStayATM,
            CloseSlowVent
        }


        //private TMPumpRoutine _pumpRoutine;
        //private TMVentRoutine _ventRoutine;
        private TM _tm;
        private IoSensor _bufferLid;
        private IoSensor _tmLid;
        private Devices.IoPump _pumpType;
        private LoadLock _ll;
        private IoInterLockEx _tmIoInterLock;
        private Stopwatch _swTimer = new Stopwatch();

        private int _routineTimeOut;
        private int _purgeCount;

        private double _slowFastPumpSwitchPressure;
        private double _pumpDelayTime;
        private double _pumpBasePressure;
        private int _pumpTimeOut;

        private double _ventBasePressure;
        private double _slowFastVentSwitchPressure;
        private int _ventTimeOut;

        private double _mfc60Default1;
        private double _mfc60Default2;

        private IoMFC _mfc60;


        private double _ventDelayTime;

        public TMPurgeRoutine()
        {
            Module = ModuleName.TM.ToString();
            Name = "Purge";

            _tm = DEVICE.GetDevice<SicTM>($"{ ModuleName.System.ToString()}.{ Module}");
            _ll = DEVICE.GetDevice<SicLoadLock>($"LoadLock.LoadLock");
            _bufferLid = DEVICE.GetDevice<IoSensor>($"Buffer.BufferLidClosed");
            _tmLid = DEVICE.GetDevice<IoSensor>($"TM.TMLidClosed");
            _pumpType = DEVICE.GetDevice<Devices.IoPump>($"TM.TMPump1");
            _tmIoInterLock = DEVICE.GetDevice<IoInterLockEx>("TM.IoInterLock");
            _mfc60 = DEVICE.GetDevice<IoMFC>($"TM.Mfc60");

            //_pumpRoutine = new TMPumpRoutine();
            //_ventRoutine = new TMVentRoutine();
        }

        public override Result Start(params object[] objs)
        {
            Reset();

            _purgeCount = SC.GetValue<int>("TM.Purge.CyclePurgeCount");
            _routineTimeOut = SC.GetValue<int>("TM.Purge.RoutineTimeOut");

            _slowFastPumpSwitchPressure = SC.GetValue<double>("TM.Purge.SlowFastPumpSwitchPressure");
            _pumpDelayTime = SC.GetValue<int>("TM.Purge.PumpDelayTime");
            _pumpBasePressure = SC.GetValue<double>("TM.Purge.PumpBasePressure");
            _pumpTimeOut = SC.GetValue<int>("TM.Purge.PumpTimeOut");

            _ventDelayTime = SC.GetValue<int>("TM.Purge.VentDelayTime");
            _mfc60Default1 = SC.GetValue<double>("TM.Purge.Mfc60Default1");
            _mfc60Default2 = SC.GetValue<double>("TM.Purge.Mfc60Default2");

            _slowFastVentSwitchPressure = SC.GetValue<double>("TM.Purge.SlowFastVentSwitchPressure");
            _ventTimeOut = SC.GetValue<int>("TM.Purge.VentTimeout");
            _ventBasePressure = SC.GetValue<double>("TM.Purge.VentBasePressure");

            ModuleName[] modules = new ModuleName[] { ModuleName.LoadLock, ModuleName.PM1, ModuleName.PM2 };
            foreach (var moduleName in modules)
            {
                if (!_tm.CheckSlitValveClose(moduleName))
                {
                    EV.PostAlarmLog(Module, $"Can not Purge, {moduleName} slit valve not closed");
                    return Result.FAIL;
                }
            }

            if (!_bufferLid.Value)
            {
                EV.PostAlarmLog(Module, $"Can not Purge,Buffer lid is not open");
                return Result.FAIL;
            }
            if (!_tmLid.Value)
            {
                EV.PostAlarmLog(Module, $"Can not Purge,TM lid is not open");
                return Result.FAIL;
            }
            if (_pumpType.IsAlarm)
            {
                EV.PostAlarmLog(Module, $"can not Purge,TM pump alarm");
                return Result.FAIL;
            }
            if (!_pumpType.IsRunning)
            {
                EV.PostAlarmLog(Module, $"can not Purge,TM pump is not running");
                return Result.FAIL;
            }
            if (!_tmIoInterLock.SetTMPurgeRoutineRunning(true, out string reason))
            {
                EV.PostAlarmLog(Module, $"can not Purge,{reason}");
                return Result.FAIL;
            }

            _tmIoInterLock.DoTmCyclePurgeRoutineSuccessed = false;

            if (SC.GetValue<bool>("System.IsATMMode"))
            {
                return Result.DONE;
            }

            _swTimer.Restart();
            Notify("Start");
            return Result.RUN;
        }


        public override Result Monitor()
        {
            try
            {
                CheckRoutineTimeOut();

                Loop((int)RoutineStep.StartLoop, _purgeCount);

                //ExecuteRoutine((int)RoutineStep.LoopPump, _pumpRoutine);

                //ExecuteRoutine((int)RoutineStep.LoopVent, _ventRoutine);

                //先Pump
                {
                    //关闭V77
                    CloseTMVent((int)RoutineStep.CloseV77);

                    //关闭V80
                    //CloseBufferVent((int)RoutineStep.CloseV80);

                    //打开V82,等待压力低于200mbar(可配置)
                    OpenSlowPump((int)RoutineStep.SlowPump, _tm, _slowFastPumpSwitchPressure, _pumpTimeOut);

                    //打开V81,压力达到0mbar(可配置)
                    OpenFastPump((int)RoutineStep.FastPump, _tm, _pumpBasePressure, _pumpTimeOut);

                    //等待5s(可配置)
                    TimeDelay((int)RoutineStep.VaccumDelay, _pumpDelayTime);

                    //关闭
                    CloseFastPump((int)RoutineStep.CloseValves, _tm);

                    CloseSlowPump((int)RoutineStep.CLoseSlowValue, _tm);
                }

                //再Vent
                {
                    //关闭V81
                    CloseFastPump((int)RoutineStep.CloseV81);

                    //关闭V82
                    CloseSlowPump((int)RoutineStep.CloseV82);

                    //设定MFC60慢充流量
                    SetMFCToSetPoint((int)RoutineStep.SetMFC1, _mfc60, _mfc60Default1);

                    ////打开V77,等待压力大于200mbar
                    //OpenSlowVent((int)RoutineStep.OpenSlowVent, _tm, _slowFastVentSwitchPressure, _slowVentTimeout);

                    ////设定MFC60快充流量
                    //SetMFCToSetPoint((int)RoutineStep.SetMFC2, _mfc60, _mfc60Default2);

                    ////等待压力大于1020mbar
                    //OpenFastVent((int)RoutineStep.OpenFastVent, _tm, _ventBasePressure, _fastVentTime);

                    //充气过程中检查是否到达打开快充流量的条件
                    OpenVent((int)RoutineStep.OpenVent, _tm, _ventBasePressure, _slowFastVentSwitchPressure, _mfc60Default2, _ventTimeOut);

                    //等待5s
                    TimeDelay((int)RoutineStep.TimeStayATM, _ventDelayTime);

                    //关闭V77
                    CloseSlowVentValve((int)RoutineStep.CloseSlowVent, _tm);
                }

                EndLoop((int)RoutineStep.StopLoop);

                //关闭V81
                CloseFastPump((int)RoutineStep.CloseV81);

                //关闭V82
                CloseSlowPump((int)RoutineStep.CloseV82);

                //关闭V77
                CloseSlowVentValve((int)RoutineStep.CloseSlowVent, _tm);
            }
            catch (RoutineBreakException)
            {
                return Result.RUN;
            }
            catch (RoutineFaildException)
            {
                return Result.FAIL;
            }

            Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");

            _tmIoInterLock.DoTmCyclePurgeRoutineRunning = false;
            _tmIoInterLock.DoTmCyclePurgeRoutineSuccessed = true;

            return Result.DONE;
        }

        public override void Abort()
        {
            _tmIoInterLock.DoTmCyclePurgeRoutineRunning = false;
            _tmIoInterLock.DoTmCyclePurgeRoutineSuccessed = false;

            base.Abort();
        }


        private void CheckRoutineTimeOut()
        {
            if (_routineTimeOut > 10)
            {
                if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
                {
                    EV.PostAlarmLog(Module, $"Routine TimeOut! over {_routineTimeOut} s");
                    throw (new RoutineFaildException());
                }
            }
        }
    }
}
