using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
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.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.SRD;
using MECF.Framework.Common.Persistent.Prewet;
using MECF.Framework.Common.Persistent.SRD;
using MECF.Framework.Common.TwinCat;
using CyberX8_Core;
using System.Reflection;
using CyberX8_RT.Modules.Rinse;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.SRD;
using CyberX8_RT.Devices.AXIS;
using MECF.Framework.Common.Persistent.Rinse;
using System.Security.Principal;
using MECF.Framework.Common.IOCore;
namespace CyberX8_RT.Devices.SRD
{
    public class SrdCommonDevice : BaseDevice, IDevice
    {
        /// 
        /// Srd操作枚举
        /// 
        private enum SrdCommonOperation
        {
            None,
            DoorClose,
            DoorOpen,
            ChuckVacuumOn,
            ChuckVacuumOff,
        }
        #region 常量
        private const string FLUID_CONTAINMENT = "FluidContainment";
        private const string VACUUM_VALUE = "VacuumValue";
        private const string WAFER_PRESENCE = "WaferPresence";
        private const string WAFER_PRESENCE_STATUS = "WaferPresenceStatus";
        private const string WATER_PRESSURE = "WaterPressure";
        private const string DOOR_CLOSE="DoorClose";
        private const string DOOR_CLOSED = "DoorClosed";
        private const string DOOR_OPENED = "DoorOpened";
        private const string WATER_ABOVE="WaterAbove";
        private const string WATER_BELOW = "WaterBelow";
        private const string CHUCK_VACUUM="ChuckVacuum";
        private const string EXHAUST_ON="ExhaustOn";
        private const string COMMON_DATA = "CommonData";
        private const string PERSISTENT_VALUE= "PersistentValue";
        #endregion
        #region 内部变量
        /// 
        /// Common数据
        /// 
        private SrdCommonData _commonData = new SrdCommonData();
        /// 
        /// 状态
        /// 
        private RState _status;
        /// 
        /// 当前操作
        /// 
        private SrdCommonOperation _currentOperation;
        /// 
        /// Wafer Presence
        /// 
        private string _waferPresence;
        /// 
        /// Persistent Value对象
        /// 
        private SRDPersistentValue _srdPersistentValue;
        /// 
        /// IsWaferPresence
        /// 
        private bool _isWaferPresence = true;
        /// 
        /// Total Device
        /// 
        private TotalSRDDevice _totalSRDDevice;
        #region Routine
        /// 
        /// Close Routine
        /// 
        private SrdCommonDoorCloseRoutine _doorCloseRoutine;
        /// 
        /// Vacuum Routine
        /// 
        private SrdCommonChuckVacuumRoutine _chuckVacuumRoutine;
        #endregion
        #endregion
        #region 属性
        /// 
        /// Common数据
        /// 
        public SrdCommonData CommonData
        {
            get { return _commonData; }
        }
        /// 
        /// 状态
        /// 
        public RState Status { get { return _status; } }
        /// 
        /// Wafer Presence
        /// 
        public string WaferPresence 
        {
            get { return _waferPresence; }
        }
        /// 
        /// IsWaferPresence
        /// 
        public bool IsWaferPresence
        {
            get { return _isWaferPresence; }
        }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        public SrdCommonDevice(string moduleName) : base(moduleName, "Common", "Common", "Common")
        {
        }      
        /// 
        /// 初始化
        /// 
        /// 
        public bool Initialize()
        {
            InitializeRoutine();
            SubscribeData();
            SubscribeValueAction();
            InitializeOperation();
            return true;
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
            _doorCloseRoutine = new SrdCommonDoorCloseRoutine(Module);
            _chuckVacuumRoutine = new SrdCommonChuckVacuumRoutine(Module);
        }
        /// 
        /// 订阅数据
        /// 
        private void SubscribeData()
        {
            _srdPersistentValue = SRDPersistentManager.Instance.GetModulePersistentValue(Module);
            if(_srdPersistentValue==null)
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module, "Persistent Value Object is not exist");
            }
            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _srdPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{COMMON_DATA}", () => _commonData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{WAFER_PRESENCE_STATUS}", () => _waferPresence, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsWaferPresence", () => IsWaferPresence, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 订阅变量数值发生变化
        /// 
        private void SubscribeValueAction()
        {
            IOModuleManager.Instance.SubscribeModuleVariable(Module, VACUUM_VALUE, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WAFER_PRESENCE, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_CLOSE, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_CLOSED, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_OPENED, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_ABOVE, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_BELOW, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, CHUCK_VACUUM, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, EXHAUST_ON, UpdateVariableValue);
        }
        /// 
        /// 初始化操作
        /// 
        private void InitializeOperation()
        {
            OP.Subscribe($"{Module}.{Name}.DoorClose", DoorCloseAction);
            OP.Subscribe($"{Module}.{Name}.DoorOpen", DoorOpenAction);
            OP.Subscribe($"{Module}.{Name}.WaterAboveOn", WaterAboveOnAction);
            OP.Subscribe($"{Module}.{Name}.WaterAboveOff", WaterAboveOffAction);
            OP.Subscribe($"{Module}.{Name}.WaterBelowOn", WaterBelowOnAction);
            OP.Subscribe($"{Module}.{Name}.WaterBelowOff", WaterBelowOffAction);
            OP.Subscribe($"{Module}.{Name}.ChuckVacuumOn", ChuckVacuumOnAction);
            OP.Subscribe($"{Module}.{Name}.ChuckVacuumOff", ChuckVacuumOffAction);
            OP.Subscribe($"{Module}.{Name}.ExhaustOn", ExhaustOnAction);
            OP.Subscribe($"{Module}.{Name}.ExhaustOff", ExhaustOffAction); 
            OP.Subscribe($"{Module}.KeyDown", KeyDownAction);
            
            OP.Subscribe($"{Module}.DisabledAction", DisabledOperation);
            OP.Subscribe($"{Module}.ManualAction", ManualOperation);
            OP.Subscribe($"{Module}.AutoAction", AutoOperation);
            OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation);
            OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation);
            OP.Subscribe($"{Module}.UpdateIsWaferPresenceAction", UpdateIsWaferPresenceAction);
        }
    
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateVariableValue(string variable, object value)
        {
            if(!CommonData.IsDataInitialized)
            {
                CommonData.IsDataInitialized = true;
            }
            PropertyInfo property = CommonData.GetType().GetProperty(variable);
            if (property != null)
            {
                property.SetValue(CommonData, value);
            }
            UpdateWaferPresence(variable, value);
        }
        /// 
        /// 更新Wafer Presence
        /// 
        private void UpdateWaferPresence(string variable,object value)
        {
            if (variable == WAFER_PRESENCE&&value is double)
            {
                UpdateWaferPresence((double)value);
            }
        }
        /// 
        /// 更新Wafer Presence
        /// 
        /// 
        private void UpdateWaferPresence(double waferPresence)
        {
            if (_srdPersistentValue != null)
            {
                if (waferPresence > _srdPersistentValue.EmptyThreshold)
                {
                    _waferPresence = "Empty";
                }
                else if (waferPresence >= _srdPersistentValue.WellPlacedHighThreshold && waferPresence <= _srdPersistentValue.EmptyThreshold)
                {
                    _waferPresence = "PoorlyPlaced";
                }
                else if (waferPresence < _srdPersistentValue.WellPlacedLowThreshold)
                {
                    _waferPresence = "PoorlyPlaced";
                }
                else
                {
                    _waferPresence = "WellPlaced";
                }
            }
        }
        
        #region Operation
        #region OperationStatus
        /// 
        /// DisabledAction
        /// 
        /// 
        /// 
        /// 
        private bool DisabledOperation(string cmd, object[] args)
        {
            string currentOperation = "Disabled";
            SRDEntity srdEntity = Singleton.Instance.GetModule(Module);
            if (srdEntity == null || _srdPersistentValue == null) return false;
            if (_srdPersistentValue.OperatingMode != "Disabled") srdEntity.EnterInit();
            SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation);
            return true;
        }
        /// 
        /// ManualAction
        /// 
        /// 
        /// 
        /// 
        private bool ManualOperation(string cmd, object[] args)
        {
            string currentOperation = "Manual";
            SRDEntity srdEntity = Singleton.Instance.GetModule(Module);
            if (srdEntity == null || _srdPersistentValue == null) return false;
            if (_srdPersistentValue.OperatingMode == "Auto" && srdEntity.IsBusy)
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module, $"{Module} is Busy, can't change to manual mode");
                return false;
            }
            if (_srdPersistentValue.OperatingMode != "Manual") srdEntity.EnterInit();
            SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation);
            return true;
        }
        /// 
        /// AutoAction
        /// 
        /// 
        /// 
        /// 
        private bool AutoOperation(string cmd, object[] args)
        {
            string currentOperation = "Auto";
            SRDEntity srdEntity = Singleton.Instance.GetModule(Module);
            if (srdEntity == null || _srdPersistentValue == null) return false;
            if (_srdPersistentValue.OperatingMode != "Auto") srdEntity.EnterInit();
            SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation);
            return true;
        }
        /// 
        /// EngineeringModeAction
        /// 
        /// 
        /// 
        /// 
        private bool EngineeringModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Engineering";
            SRDPersistentManager.Instance.UpdateRecipeOperationModeValue(Module, currentRecipeOperation);
            return true;
        }
        /// 
        /// ProductionAction
        /// 
        /// 
        /// 
        /// 
        private bool ProductionModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Production";
            SRDPersistentManager.Instance.UpdateRecipeOperationModeValue(Module, currentRecipeOperation);
            return true;
        }
        #endregion
        #region keydown
        private bool KeyDownAction(string cmd, object[] args)
        {
            string variableName = args[0].ToString();
            PropertyInfo property = _srdPersistentValue.GetType().GetProperty(variableName);
            if(property!=null)
            {
                property.SetValue(_srdPersistentValue, args[1]);
            }
            SRDPersistentManager.Instance.UpdateModulePersistentValue(Module);
            UpdateWaferPresence(CommonData.WaferPresence);
            return true;
        }
        #endregion
        #region Door 
        /// 
        /// Door Close操作
        /// 
        public bool DoorCloseAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.DoorClose))
            {
                _currentOperation = SrdCommonOperation.DoorClose;
                _status = _doorCloseRoutine.Start(true);
                return _status==RState.Running;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// Door Open操作
        /// 
        public bool DoorOpenAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.DoorOpen))
            {
                _currentOperation = SrdCommonOperation.DoorOpen;
                _status = _doorCloseRoutine.Start(false);
                return _status==RState.Running;
            }
            else
            {
                return false;
            }
        }
        #endregion
        #region Exhaust On
        /// 
        /// Exhaust On
        /// 
        /// 
        /// 
        /// 
        public bool ExhaustOnAction(string cmd, object[] args)
        {
            return ExhaustOn();
        }
        /// 
        /// Exhaust Off
        /// 
        /// 
        /// 
        /// 
        public bool ExhaustOffAction(string cmd, object[] args)
        {
            return ExhaustOff();
        }
        /// 
        /// Exhaust On(不确认信号)
        /// 
        /// 
        public bool ExhaustOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{EXHAUST_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Exhaust On(不确认信号)
        /// 
        /// 
        public bool ExhaustOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{EXHAUST_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        #region Chuck Vacuum 
        /// 
        /// Chuck Vacuum操作
        /// 
        public bool ChuckVacuumOnAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.ChuckVacuumOn))
            {
                _currentOperation = SrdCommonOperation.ChuckVacuumOn;
                _status = _chuckVacuumRoutine.Start(false);
                return _status==RState.Running;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// chuck Vacuum Off操作
        /// 
        public bool ChuckVacuumOffAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.ChuckVacuumOff))
            {
                _currentOperation = SrdCommonOperation.ChuckVacuumOff;
                _status= _chuckVacuumRoutine.Start(true);
                return _status==RState.Running;
            }
            else
            {
                return false;
            }
        }
        #endregion
        #region Water Above 
        /// 
        /// Water Above On操作
        /// 
        public bool WaterAboveOnAction(string cmd, object[] args)
        {
            return WaterAboveOn();
        }
        /// 
        /// water above Off操作
        /// 
        public bool WaterAboveOffAction(string cmd, object[] args)
        {
            return WaterAboveOff();
        }
        /// 
        /// Water Above On(不确认信号)
        /// 
        /// 
        public bool WaterAboveOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Water Above Off(不确认信号)
        /// 
        /// 
        public bool WaterAboveOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        #region Water Below 
        /// 
        /// Water Below On操作
        /// 
        public bool WaterBelowOnAction(string cmd, object[] args)
        {
            return WaterBelowOn();
        }
        /// 
        /// water Below Off操作
        /// 
        public bool WaterBelowOffAction(string cmd, object[] args)
        {
            return WaterBelowOff();
        }
        /// 
        /// Water Below On(不确认信号)
        /// 
        /// 
        public bool WaterBelowOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Water Below Off(不确认信号)
        /// 
        /// 
        public bool WaterBelowOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        /// 
        /// Update IsWaferPresence 标志位
        /// 
        /// 
        /// 
        /// 
        public bool UpdateIsWaferPresenceAction(string cmd, object[] args)
        {
            _isWaferPresence = (bool)args[0];
            return true; 
        }
        /// 
        /// 判定运行状态
        /// 
        /// 
        private bool JudgeRunningState(SrdCommonOperation operation)
        {
            if (_status == RState.Running)
            {
                EV.PostAlarmLog($"{Module}", eEvent.ERR_SRD, $"{Module} current execute {_currentOperation},cannot {operation}");
                return true;
            }
            return false;
        }
        /// 
        /// ErrorOperation
        /// 
        public void EnterErrorOperation()
        {
            //关闭风扇
            if (CommonData.ExhaustOn)
            {
                bool result = ExhaustOffAction("", null);
                if (!result)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, Module, "EnterError: Exhaust Off is failed");
                }
            }
            //关闭WaterAbove
            if (CommonData.WaterAbove)
            {
                bool result = WaterAboveOff();
                if (!result)
                {
                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Above Off is failed");
                }
            }
            //关闭WaterBelow
            if (CommonData.WaterBelow)
            {
                bool result = WaterBelowOff();
                if (!result)
                {
                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Below Off is failed");
                }
            }
            //停电机
            JetAxisBase _armAxis = DEVICE.GetDevice($"{Module}.Arm");
            if (_armAxis != null && _armAxis.IsRun) _armAxis.StopPositionOperation();
            JetAxisBase _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            if (_rotationAxis != null && _rotationAxis.IsRun) _rotationAxis.StopPositionOperation();
        }
        #endregion
        /// 
        /// 定时器
        /// 
        /// 
        public bool OnTimer()
        {
            if (_status == RState.Running)
            {
                if (_currentOperation != SrdCommonOperation.None)
                {
                    IRoutine routine = GetCurrentRoutine(_currentOperation);
                    if (routine != null)
                    {
                        CheckRoutineState(routine, _currentOperation);
                    }
                    else
                    {
                        EndOperation();
                    }
                }
            }
            //将公有的数据赋值于对象的数值
            if (_totalSRDDevice == null)
            {
                _totalSRDDevice = DEVICE.GetDevice("SRD");
            }
            if (_totalSRDDevice != null)
            {
                CommonData.FluidContainment = _totalSRDDevice.FluidContainment;
                CommonData.WaterPressure = _totalSRDDevice.WaterPressure;
            }
            return true;
        }
        /// 
        /// 获取当前操作对应的Routine
        /// 
        /// 
        /// 
        private IRoutine GetCurrentRoutine(SrdCommonOperation currentOperation)
        {
            switch (currentOperation)
            {
                case SrdCommonOperation.DoorClose:
                case SrdCommonOperation.DoorOpen:
                    return _doorCloseRoutine;
                case SrdCommonOperation.ChuckVacuumOn:
                case SrdCommonOperation.ChuckVacuumOff:
                    return _chuckVacuumRoutine;
                default:
                    return null;
            }
        }
        /// 
        /// 检验Routine状态
        /// 
        /// 
        /// 
        private void CheckRoutineState(IRoutine routine, SrdCommonOperation currentOperation)
        {
            RState state = routine.Monitor();
            if (state == RState.End)
            {
                EndOperation();
            }
            else if (state == RState.Failed || state == RState.Timeout)
            {
                LOG.WriteLog(eEvent.ERR_SRD, $"{Module}", $"{currentOperation} error");
                EndOperation();
            }
        }
        /// 
        /// 结束操作
        /// 
        private void EndOperation()
        {
            _status = RState.End;
            _currentOperation = SrdCommonOperation.None;
        }
        #region 设备接口
        /// 
        /// 监控
        /// 
        public void Monitor()
        {
        }
        public void Reset()
        {
        }
        public void Terminate()
        {
        }
        #endregion
    }
}