using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Sorter.Common;
using Venus_RT.Devices;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using Venus_Core;
using Aitex.Core.RT.Log;
using Aitex.Core.Common;
using Aitex.Core.Util;
using MECF.Framework.Common.Schedulers;
using System.Collections.Generic;
using Venus_RT.Devices.EFEM;

namespace Venus_RT.Modules.EFEM
{
    class EfemHomeRoutine : ModuleRoutineBase, IRoutine
    {
        private enum HomeStep
        {
            WaitEFEMReady,
            ClearError,
            InitRobot,
            HomeAllAxes,
            CheckWaferPresence,
            End,
        }

        private enum HomeModuleStep
        {
            Home,
            HomeAxes,
            End,
        }

        private int _homeTimeout = 30 * 1000;
        ModuleName _targetModule;
        EfemBase _efem;

        public EfemHomeRoutine(EfemBase efem) : base(ModuleName.EfemRobot)
        {
            _efem = efem;
        }

        public RState Start(params object[] objs)
        {

            _targetModule = (ModuleName)objs[0];

            _homeTimeout = SC.GetValue<int>($"EFEM.HomeTimeout") * 1000;
            return Runner.Start(Module, $"Home {_targetModule}");
        }

        public RState Monitor()
        {

            if(_targetModule == ModuleName.EFEM)
            {
                Runner.Wait(HomeStep.WaitEFEMReady,        WaitEFEMIdle,            _delay_60s)
                    .Run(HomeStep.ClearError,              ClearError,             IsStepComplete,         _homeTimeout)
                    .Run(HomeStep.InitRobot,               HomeAll,                IsStepComplete,         _homeTimeout)
                    .Run(HomeStep.HomeAllAxes,             HomeAllAxes,            IsStepComplete,         _homeTimeout)
                    .Run(HomeStep.CheckWaferPresence,      CheckWaferPresence,     VerifyWaferPresence,    _homeTimeout)
                    .End(HomeStep.End,                     NullFun,                _delay_50ms);
            }
            else
            {
                Runner.Wait(HomeStep.WaitEFEMReady,     WaitEFEMIdle,       _delay_60s)
                    .Run(HomeModuleStep.Home,           HomeModule,         IsStepComplete,     _homeTimeout)
                    .Run(HomeModuleStep.HomeAxes,       HomeModuleAxes,     IsStepComplete,     _homeTimeout)
                    .End(HomeModuleStep.End,            NullFun,            _delay_50ms);
            }


            return Runner.Status;
        }

        public void Abort()
        {
        }

        private bool IsStepComplete()
        {

            if (_efem.Status == RState.End)
            {
                return true;
            }
            else if (_efem.Status == RState.Failed || _efem.Status == RState.Timeout)
            {
                Runner.Stop($"Efem home failed: {_efem.Status}");
                //LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Efem home failed: {_efem.Status}");
                return true;
            }
            else
                return false;
        }

        private bool WaitEFEMIdle()
        {
            return _efem.Status != RState.Running;
        }

        private bool ClearError()
        {
            return _efem.ClearError();
        }

        private bool HomeAll()
        {
            return _efem.HomeAll();
        }

        private bool HomeModule()
        {
            return _efem.Home(_targetModule);
        }

        private bool HomeAllAxes()
        {
            return _efem.OriginalSearch(ModuleName.EFEM);
        }

        private bool HomeModuleAxes()
        {
            return _efem.OriginalSearch(_targetModule);
        }

        private bool CheckWaferPresence()
        {
            return _efem.CheckWaferPresence();
        }

        private bool VerifyWaferPresence()
        {
            if (_efem.Status == RState.End)
            {
                var waferPresence = _efem.GetWaferPresence();
                //000/111 upperArmWafer, lowerArmWafer, alignerWafer1, 
                if (waferPresence.Length != 3)
                {
                    LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"EFEM Track wafer present return invalid value, Wafer Presence:{waferPresence}, should be 3 characters");
                    return false;
                }

                //upper arm
                if (waferPresence[0] == '1')
                {
                    if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1))
                    {
                        WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 1,  WaferStatus.Normal);
                    }
                }
                else
                {
                    if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1))
                    {
                        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.EfemRobot} upper arm has wafer information, while EFEM return empty, manually delete if really no wafer");
                    }
                }

                //lower arm
                if (waferPresence[1] == '1')
                {
                    if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0))
                    {
                        WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 0, WaferStatus.Normal);
                    }
                }
                else
                {
                    if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0))
                    {
                        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.EfemRobot} lower arm has wafer information, while EFEM return empty, manually delete if really no wafer");
                    }
                }

                //aligner1
                if (waferPresence[2] == '1')
                {
                    if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner1, 0))
                    {
                        WaferManager.Instance.CreateWafer(ModuleName.Aligner1, 0, WaferStatus.Normal);
                    }
                }
                else
                {
                    if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0))
                    {
                        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.Aligner1} has wafer information, while EFEM return empty, manually delete if really no wafer");
                    }
                }

                //aligner2
                //if (waferPresence[3] == '1')
                //{
                //    if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner2, 0))
                //    {
                //        WaferManager.Instance.CreateWafer(ModuleName.Aligner2, 0, WaferStatus.Normal);
                //    }
                //}
                //else
                //{
                //    if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner2, 0))
                //    {
                //        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.Aligner2} has wafer information, while EFEM return empty, manually delete if really no wafer");
                //    }
                //}

                //cooling1
                //if (waferPresence[4] == '1')
                //{
                //    if (WaferManager.Instance.CheckNoWafer(ModuleName.Cooling1, 0))
                //    {
                //        WaferManager.Instance.CreateWafer(ModuleName.Cooling1, 0, WaferStatus.Normal);
                //    }
                //}
                //else
                //{
                //    if (WaferManager.Instance.CheckHasWafer(ModuleName.Cooling1, 0))
                //    {
                //        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.Cooling1} has wafer information, while EFEM return empty, manually delete if really no wafer");
                //    }
                //}

                //cooling2
                //if (waferPresence[5] == '1')
                //{
                //    if (WaferManager.Instance.CheckNoWafer(ModuleName.Cooling2, 0))
                //    {
                //        WaferManager.Instance.CreateWafer(ModuleName.Cooling2, 0, WaferStatus.Normal);
                //    }
                //}
                //else
                //{
                //    if (WaferManager.Instance.CheckHasWafer(ModuleName.Cooling2, 0))
                //    {
                //        LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.Cooling2} has wafer information, while EFEM return empty, manually delete if really no wafer");
                //    }
                //}
                return true;
            }
            else if (_efem.Status != RState.Running)
            {
                LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Efem StateTrack failed: {_efem.Status}");
                return true;
            }
            else
                return false;
        }

    }
}