using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.Facilities;
using PunkHPX8_RT.Devices.PlatingCell;
using PunkHPX8_RT.Devices.Reservoir;
using PunkHPX8_RT.Devices.Temperature;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.Reservoir
{
    public class DMReservoirInitializeRoutine : RoutineBase, IRoutine
    {
        private enum InitializeStep
        {
            OpenIsolationValve,
            CAPump,
            CAPumpWait,
            ANPump,
            ANPumpWait,
            CheckFlowWait,
            CellManualCheckFlow,
            CellAutoCheckFlow,
            CheckDiReplen,
            AutoDiReplen,
            AutoCellAutoEnableHED,
            AutoCellAutoEnableHEDDelay,
            AutoCellAutoEnableHEDCheck,
            End
        }
        #region 常量 
        private const string AUTO = "Auto";
        private const string MANUAL = "Manual";
        private const int ENABLE = 5;
        #endregion
        #region 内部变量
        CAPumpOnRoutine _caPumpOnRoutine;
        ANPumpOnRoutine _anPumpOnRoutine;
        DMReservoirDevice _dmReservoirDevice;
        private ResRecipe _recipe;
        private PlatingCellDevice _platingCellDevices;
        private TemperatureController _temperatureController;
        private double _hedFlowLowLimit;
        private int _autoHedDelay = 0;
        private int _flowFaultHoldOffTime = 1000;
        private double _cellFlowStartLowLimit = 3;
        private double _anFlowStartLowLimit = 0.5;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public DMReservoirInitializeRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            _caPumpOnRoutine.Abort();
            _anPumpOnRoutine.Abort();
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(InitializeStep.OpenIsolationValve, OpenIsolationValve,_delay_1ms)
                  .Run(InitializeStep.CAPump, () => { return _caPumpOnRoutine.Start() == RState.Running; }, _delay_1s)
                  .WaitWithStopCondition(InitializeStep.CAPumpWait, () => CommonFunction.CheckRoutineEndState(_caPumpOnRoutine), () => CommonFunction.CheckRoutineStopState(_caPumpOnRoutine))
                  .Run(InitializeStep.ANPump, () => { return _anPumpOnRoutine.Start() == RState.Running; }, _delay_1ms)
                  .WaitWithStopCondition(InitializeStep.ANPumpWait, () => CommonFunction.CheckRoutineEndState(_anPumpOnRoutine), () => CommonFunction.CheckRoutineStopState(_anPumpOnRoutine))
                  .Delay(InitializeStep.CheckFlowWait, _flowFaultHoldOffTime)
                  .RunIf(InitializeStep.CellManualCheckFlow,_dmReservoirDevice.OperationMode == MANUAL,ManualCheckFlow,_delay_1ms)
                  .RunIf(InitializeStep.CellAutoCheckFlow,_dmReservoirDevice.OperationMode == AUTO, AutoCheckFlow, _delay_1ms)
                  .RunIf(InitializeStep.AutoDiReplen, _recipe.DIReplenEnable || _recipe.ANDIReplenEnable, CheckFacilitiesDiReplenStatus, _delay_1ms)
                  .Run(InitializeStep.AutoCellAutoEnableHED, AutoHedOn, _delay_1ms)
                  .Delay(InitializeStep.AutoCellAutoEnableHEDDelay, _autoHedDelay)
                  .Run(InitializeStep.AutoCellAutoEnableHEDCheck, AutoHedSuccess, _delay_1ms)
                  .End(InitializeStep.End, ClearAlarmDataError, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 打开Isolation valve
        /// 
        /// 
        private bool OpenIsolationValve()
        {
            return _dmReservoirDevice.ANIsolationOn() && _dmReservoirDevice.CAIsolationOn() && _dmReservoirDevice.ReturnValveOn("",null);
        }
        /// 
        /// 检查cell flow 和an flow是否大于配置项
        /// 
        /// 
        private bool ManualCheckFlow()
        {
            if(_dmReservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit)
            {
                _dmReservoirDevice.CAPumpOff("",null);
                _dmReservoirDevice.CAIsolationOff();
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CA Flow is less than cellFlowStartLowLimit ");
                return false;
            }
            if(_dmReservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit)
            {
                _dmReservoirDevice.AnPumpOff();
                _dmReservoirDevice.ANIsolationOff();
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "AN Flow is less than ANFlowStartLowLimit");
                return false;
            }
            return true;
        }
        /// 
        /// 检查cell flow 和an flow是否大于recipe的设定
        /// 
        /// 
        private bool AutoCheckFlow()
        {
            if (_dmReservoirDevice.ReservoirData.CaFlow < _recipe.CAFlowRateErrorLow)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CA Flow is less than recipe CAFlowRateErrorLow");
                return false;
            }
            if (_dmReservoirDevice.ReservoirData.AnFlow < _recipe.ANFlowRateErrorLow)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "AN Flow is less than recipe ANFlowRateErrorLow");
                return false;
            }
            return true;
        }
        /// 
        /// 检验总Di有没有开
        /// 
        /// 
        private bool CheckFacilitiesDiReplenStatus()
        {
            SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities");
            if (systemFacilities != null)
            {
                bool result = systemFacilities.DIReplenEnable;
                if (!result)
                {
                    LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Facilities DiReplen is disable");
                }
                return result;
            }
            return false;
        }
       
        /// 
        /// 自动HED On
        /// 
        /// 
        private bool AutoHedOn()
        {
            bool result = _dmReservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit;
            if (result)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"CA Flow {_dmReservoirDevice.ReservoirData.CaFlow} is less than CellFlowStartLowLimit{_cellFlowStartLowLimit}");
                return false;
            }
            _autoHedDelay = _delay_2s;
            result = _temperatureController.EnableOperation("", null);
            if (!result)
            {
                return false;
            }
            result = _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint });
            if (!result)
            {
                return false;
            }
            return true;
        }
        /// 
        /// 检验Hed是否成功
        /// 
        /// 
        private bool AutoHedSuccess()
        {
            if (_temperatureController.TemperatureData.ControlOperationModel == 0)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature control is disable");
                return false;
            }
            if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"recipe temperature {_recipe.TemperatureSetPoint} is not match temperature target point {_temperatureController.TemperatureData.TargetTemperature}");
                return false;
            }
            return true;
        }
        /// 
        /// 清除alarm界面相关的dataerror
        /// 
        private bool ClearAlarmDataError()
        {
            //AlarmListManager.Instance.RemoveDataError(Module);
            //_dmReservoirDevice.ClearErrorLogSet(Module); //清除device里面的ErrorLogSet
            return true;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _caPumpOnRoutine = new CAPumpOnRoutine(Module);
            _anPumpOnRoutine = new ANPumpOnRoutine(Module);
            _dmReservoirDevice = DEVICE.GetDevice(Module);
            //_dmReservoirDevice.ClearErrorLogSet(Module);
            _platingCellDevices = (PlatingCellDevice)objs[0];
            
            _temperatureController = (TemperatureController)objs[1];
            _recipe = _dmReservoirDevice.Recipe;
            _flowFaultHoldOffTime = SC.GetValue($"PlatingCell.FlowFaultHoldOffTime");
            _cellFlowStartLowLimit = SC.GetValue($"PlatingCell.CellFlowStartLowLimit");
            _anFlowStartLowLimit = SC.GetValue($"PlatingCell.ANFlowStartLowLimit");
            if (!CheckPreCondition())
            {
                return RState.Failed;
            }
            return Runner.Start(Module, "Start D&M Initialize");
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        private bool CheckPreCondition()
        {
            if (_recipe == null)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "recipe is null");
                return false;
            }
            if (!_temperatureController.IsConnected)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature is not connected");
                return false;
            }
            if (!CheckFacility())
            {
                return false;
            }
            return true;
        }
        /// 
        /// 检验facility
        /// 
        /// 
        private bool CheckFacility()
        {
            SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities");
            if (systemFacilities != null)
            {
                if (!systemFacilities.HouseChilledWaterEnable)
                {
                    LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "HouseChilledWaterEnable is false");
                    return false;
                }
                if (!systemFacilities.DIFillEnable)
                {
                    LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIFillEnable is false");
                    return false;
                }
                if (!systemFacilities.DIReplenEnable)
                {
                    LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
                    return false;
                }
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "DIReplenEnable is false");
                return false;
            }
            return true;
        }
    }
}