using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.RT.ModuleLibrary.VceModules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Venus_Core;
using Venus_RT.Devices;
using Venus_RT.Devices.SMIF;
using Venus_RT.Modules.TM.VenusEntity;

namespace Venus_RT.Modules.VCE
{
    public class UnloadWithSMIFRoutine : ModuleRoutineBase, IRoutine
    {
        public enum UnloadWithSMIFStep
        {
            CloseDoor,
            Vent,
            GotoUnload,
            OpenOutDoor,
            SMIFUnload,
            CloseOutDoor,
            NotifyOver
        }

        VceModuleBase _vce;
        ISMIF _smif;
        int _vcetimeout;
        int _smiftimeout;
        SEMFVentRoutine ventRoutine;
        public UnloadWithSMIFRoutine(ModuleName module,VceModuleBase vce,ISMIF smif) : base(module)
        {
            _vce = vce;
            _smif = smif;
            ventRoutine = new SEMFVentRoutine(DEVICE.GetDevice<HongHuTM>("SETM"), module);
        }

        public RState Start(params object[] objs)
        {
            _vcetimeout = SC.GetValue<int>($"{Module}.MotionTimeout") * 1000;
            _smiftimeout = SC.GetValue<int>($"{Module}.SMIF.MotionTimeout") * 1000;
            Reset();
            return Runner.Start(Module, "VCE Unload with SMIF");
        }
        public RState Monitor()
        {
            Runner.Run(UnloadWithSMIFStep.CloseDoor,        CloseDoor,          CheckDoorIsClose)
                  .Run(UnloadWithSMIFStep.Vent,             Vent,               CheckVentOver)
                  .Run(UnloadWithSMIFStep.GotoUnload,       GotoUnload,         CheckVceIdle,       _vcetimeout)
                  .Run(UnloadWithSMIFStep.OpenOutDoor,      OpenOutDoor,        CheckVceIdle,       _vcetimeout)
                  .Run(UnloadWithSMIFStep.SMIFUnload,       SMIFUnload,         CheckSMIFIdle,      _smiftimeout)
                  .Run(UnloadWithSMIFStep.CloseOutDoor,     CloseOutDoor,       CheckVceIdle,       _vcetimeout)
                  .End(UnloadWithSMIFStep.NotifyOver,       NullFun, 100);
            return Runner.Status;
        }

        private bool CloseDoor()
        {
            OP.DoOperation("SETM.SetSlitDoor", ModuleName.VCE1, false);
            return true;
        }

        private bool CheckDoorIsClose()
        {
            return Singleton<RouteManager>.Instance.seTM.IsVCESlitDoorClosed;
        }

        private bool CheckVentOver()
        {
            RState ret = ventRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                _vce.PostMsg(VceMSG.Error);
            }
            return ret == RState.End;
        }

        private bool Vent()
        {
            return ventRoutine.Start() == RState.Running;
        }

        private bool SMIFUnload()
        {
            _smif.Unload();
            return true;
        }

        private bool CheckSMIFIdle()
        {
            return true;
        }

        private bool CloseOutDoor()
        {
            return _vce.CloseDoor();
        }
        private bool OpenOutDoor()
        {
            if (Singleton<RouteManager>.Instance.seTM.VCEIsATM && Singleton<RouteManager>.Instance.seTM.VCEPressure >= SC.GetValue<int>($"{Module}.OutDoorOpenPressure"))
            {
                return _vce.OpenDoor();
            }
            else
            {
                LOG.Write(eEvent.ERR_VCE_COMMON_Failed, Module, $"{Module} is not ATM or Pressure not arrive {SC.GetValue<int>($"{Module}.OutDoorOpenPressure")}");
                return false;
            }
        }

        private bool GotoUnload()
        {
            return _vce.GotoLP();
        }

        private bool CheckVceIdle()
        {
            if (_vce.Status == RState.Failed || _vce.Status == RState.Timeout)
            {
                Singleton<RouteManager>.Instance.GetVCE(Module).PostMsg(VceMSG.Error);
                return false;
            }
            return _vce.Status == RState.End;
        }


        public void Abort()
        {

        }

    }
}