using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using CyberX8_Core;
using CyberX8_RT.Devices.Reservoir;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.Routine;
using System;
using System.Collections.Generic;

namespace CyberX8_RT.Modules.Reservoir
{
    public class DosingSystemInitializeRoutine : RoutineBase, IRoutine
    {
        private enum InitializeStep
        {
            CheckState,
            InitData,
            End
        }
        #region 内部变量
        /// <summary>
        /// 模块名称
        /// </summary>
        private string _moduleName;
        /// <summary>
        /// SHReservoirDevice
        /// </summary>
        private StandardHotReservoirDevice _standardHotReservoirdevice;
        /// <summary>
        /// Replen Persistent Value
        /// </summary>
        private Dictionary<string, ReplenPersistentValue> _replenPersistentValue = new Dictionary<string, ReplenPersistentValue>();
        #endregion

        #region 属性
        /// <summary>
        /// 当前子状态机
        /// </summary>
        public string CurrentStateMachine
        {
            get { return Runner.CurrentStep.ToString(); }
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="module"></param>
        public DosingSystemInitializeRoutine(string module) : base(module)
        {
            _moduleName = module;
        }

        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }

        public RState Monitor()
        {
            Runner.Run(InitializeStep.CheckState, CheckState, NullFun, _delay_1ms)
                .Run(InitializeStep.InitData, InitData, NullFun, _delay_1ms)
                .End(InitializeStep.End, NullFun);

            return Runner.Status;
        }
        /// <summary>
        /// CheckState
        /// </summary>
        /// <returns></returns>
        private bool CheckState()
        {
            _standardHotReservoirdevice = DEVICE.GetDevice<StandardHotReservoirDevice>($"{_moduleName}");
            if (_standardHotReservoirdevice == null)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, _moduleName, "Reservoir Device is not exist");
                return false;
            }

            for (int i = 0; i < _standardHotReservoirdevice.ReplenNum; i++)
            {
                if (_standardHotReservoirdevice.ReplenDatas[i].ReplenPumpEnable)
                {
                    //未关则关闭Replen Pump
                    Object[] args = new object[1];
                    args[0] = "Replen"+(i+1).ToString();
                    bool result = _standardHotReservoirdevice.ReplenPumpOffOperation("", args);
                    if (result)
                    {
                        LOG.WriteLog(eEvent.INFO_RESERVOIR, _moduleName, "Replen Pump Off");
                    }
                    else
                    {
                        LOG.WriteLog(eEvent.ERR_RESERVOIR, _moduleName, "Replen Pump Off is failed");
                        return false;
                    }
                }

            }

            return true;
        }
        /// <summary>
        /// Clear Data
        /// </summary>
        /// <returns></returns>
        private bool InitData()
        {
                       
            for (int i = 0; i < _standardHotReservoirdevice.ReplenNum; i++)
            {
                
                string replenName = "Replen" + (i + 1).ToString();
                _replenPersistentValue[replenName] = ReplenPersistentManager.Instance.GetReplenPersistentValue(_moduleName, replenName);
                if (_replenPersistentValue[replenName] == null)
                {
                    LOG.WriteLog(eEvent.ERR_RESERVOIR, _moduleName, $"{replenName} persistent file is null");
                    return false;
                }
                _replenPersistentValue[replenName].CurrentDosingVolume = 0;
                _replenPersistentValue[replenName].AutoDosingStartAmpHour = 0;
                _replenPersistentValue[replenName].AutoDosingStartTime = DateTime.MinValue;
                _replenPersistentValue[replenName].IsDosingRunning = false;
                _replenPersistentValue[replenName].TargetDosingVolume = 0;
                ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, replenName);
                _standardHotReservoirdevice.CheckandUpdateBottleLevel(replenName);
                _standardHotReservoirdevice.ReplenDatas[i].IsAutoDosingError = false;
            }           
            
            return true;
        }
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        public RState Start(params object[] objs)
        {
            return Runner.Start(Module, "DosingSystem Initialize");
        }
    }
}