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.Loader;
using MECF.Framework.Common.TwinCat;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS.CANOpen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.IOCore;
namespace CyberX8_RT.Devices.Loader
{
    public class LoaderCommonDevice : BaseDevice, IDevice
    {
        private enum LoaderCommonOperation
        {
            None,
            WaferHolderClampOn,
            WaferHolderClampOff,
            WaferHolderSideABClampOn,
            WaferHolderSideABClampOff,
            LeakFlowClampOn,
            LeakFlowClampOff,
            LeakVacuumOn,
            LeakVacuumOff,
            FlowTest,
            StopFlowTest
        }
        #region 常量
        private const string WAFER_HOLDER_PRESENT = "WaferHolderPresent";
        private const string WAFER_HOLDER_CLAMP = "WaferHolderClamp";
        private const string DRIP_TRAY_FLUID="DripTrayFluid";
        private const string WS_SIDE_CLAMP = "WSSideABClamp";
        private const string SIDEA_WAFER_HOLDER_CLAMP="SideAWaferHolderClamp";
        private const string SIDEB_WAFER_HOLDER_CLAMP = "SideBWaferHolderClamp";
        private const string LEAK_FLOW = "LeakFlow";
        private const string LEAK_FLOW_CLAMP = "LeakFlowClamp";
        private const string LEAK_VACUUM = "LeakVacuum";
        private const string LEAK_VACUUM_VALUE = "LeakVacuumValue";
        private const string COMMON_DATA = "CommonData";
        #endregion
        #region 内部变量
        /// 
        /// 数据
        /// 
        private LoaderCommonData _commonData = new LoaderCommonData();
        /// 
        /// 状态
        /// 
        private RState _status;
        /// 
        /// 当前操作
        /// 
        private LoaderCommonOperation _currentOperation;
        /// 
        /// Flow LotTrackDatas
        /// 
        private List _flowDatas = new List();
        #region Routine
        /// 
        /// Wafer Holder Side Clamp Routine
        /// 
        private LoaderCommonWaferHolderSideClampRoutine _sideClampRoutine;
        /// 
        /// Flow Test Routine
        /// 
        private LoaderFlowTestRoutine _flowTestRoutine;
        #endregion
        #endregion
        #region 属性
        /// 
        /// Flow LotTrackData
        /// 
        public List FlowLotTrackDatas { get { return _flowDatas; } }
        /// 
        /// 数据
        /// 
        public LoaderCommonData CommonData { get { return _commonData; } set { _commonData = value; } }
        /// 
        /// 状态
        /// 
        public RState Status { get { return _status; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        /// 
        public LoaderCommonDevice(string moduleName) : base(moduleName, "Common", "Common", "Common")
        {
        }
        /// 
        /// 初始化
        /// 
        /// 
        public bool Initialize()
        {
            InitializeRoutine();
            SubscribeData();
            SubscribeValueAction();
            InitializeOpertation();
            return true;
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
            _sideClampRoutine = new LoaderCommonWaferHolderSideClampRoutine(Module);
            _flowTestRoutine = new LoaderFlowTestRoutine(Module);
        }
        /// 
        /// 订阅数据
        /// 
        private void SubscribeData()
        {
            if(SC.ContainsItem($"{Module}.LeakTestLSOKLimit"))
            {
                _commonData.LeakMajor = SC.GetValue($"{Module}.LeakTestLSOKLimit");
            }
            if(SC.ContainsItem($"{Module}.LeakTestCutOffValue"))
            {
                _commonData.LeakMinor = SC.GetValue($"{Module}.LeakTestCutOffValue");
            }
            DATA.Subscribe($"{Module}.{COMMON_DATA}", () => _commonData);
            DATA.Subscribe($"{Module}.DripTrayFluid", () => _commonData.DripTrayFluid, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.SideAWaferShuttleClamp", () => _commonData.SideAWaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.SideBWaferShuttleClamp", () => _commonData.SideBWaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WaferShuttleClamp", () => _commonData.WaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WaferShuttlePresent", () => _commonData.WaferHolderPresent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakFlow", () => _commonData.LeakFlow, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakFlowClamp", () => _commonData.LeakFlowClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakMinor", () => _commonData.LeakMinor, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakMajor", () => _commonData.LeakMajor, SubscriptionAttribute.FLAG.IgnoreSaveDB); 
            DATA.Subscribe($"{Module}.LeakVacuum", () => _commonData.LeakVacuum, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakVacuumValue", () => _commonData.LeakVacuumValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LeakStatus", () => _commonData.LeakStatus, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 订阅变量数值发生变化
        /// 
        private void SubscribeValueAction()
        {
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WAFER_HOLDER_PRESENT, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WAFER_HOLDER_CLAMP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", DRIP_TRAY_FLUID, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", WS_SIDE_CLAMP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", SIDEA_WAFER_HOLDER_CLAMP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", SIDEB_WAFER_HOLDER_CLAMP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LEAK_FLOW, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LEAK_FLOW_CLAMP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LEAK_VACUUM, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", LEAK_VACUUM_VALUE, UpdateVariableValue);
        }
        /// 
        /// 初始化操作
        /// 
        private void InitializeOpertation()
        {
            OP.Subscribe($"{Module}.{Name}.WaferHolderClampOn",(cmd,args)=> { return WaferHolderClampOnAction(); });
            OP.Subscribe($"{Module}.{Name}.WaferHolderClampOff",(cmd,args)=> { return WaferHolderClampOffAction(); });
            OP.Subscribe($"{Module}.{Name}.WaferHolderSideClampOn", WaferHolderSideClampOnAction);
            OP.Subscribe($"{Module}.{Name}.WaferHolderSideClampOff", WaferHolderSideClampOffAction);
            OP.Subscribe($"{Module}.{Name}.LeakFlowClampOn", (cmd,args)=> { return LeakFlowClampOnAction(); });
            OP.Subscribe($"{Module}.{Name}.LeakFlowClampOff", (cmd, args) => { return LeakFlowClampOffAction(); });
            OP.Subscribe($"{Module}.{Name}.LeakVacuumOn", (cmd, args) => { return LeakVacuumOnAction(); });
            OP.Subscribe($"{Module}.{Name}.LeakVacuumOff", (cmd, args) => { return LeakVacuumOffAction(); });
            OP.Subscribe($"{Module}.Common.StartFlowTest", (cmd, args) => { return StartFlowTestAction(); });
            OP.Subscribe($"{Module}.Common.StopFlowTest", (cmd, args) => { return StopFlowTestAction(); });
        }
        #region Operation
        /// 
        /// Wafer Holder Clamp On操作
        /// 
        public bool WaferHolderClampOnAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WAFER_HOLDER_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Wafer Holder Clamp Off操作
        /// 
        public bool WaferHolderClampOffAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WAFER_HOLDER_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        /// 
        /// Wafer Holder Side Clamp On操作
        /// 
        private bool WaferHolderSideClampOnAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(LoaderCommonOperation.WaferHolderSideABClampOn))
            {
                _currentOperation = LoaderCommonOperation.WaferHolderSideABClampOn;
                _status = _sideClampRoutine.Start(true);
                return true;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// Wafer Holder Side Clamp Off操作
        /// 
        private bool WaferHolderSideClampOffAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(LoaderCommonOperation.WaferHolderSideABClampOff))
            {
                _currentOperation = LoaderCommonOperation.WaferHolderSideABClampOff;
                _status = _sideClampRoutine.Start(false);
                return true;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// Leak Flow Clamp On操作
        /// 
        public bool LeakFlowClampOnAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LEAK_FLOW_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Leak Flow Clamp Off操作
        /// 
        public bool LeakFlowClampOffAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LEAK_FLOW_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        /// 
        /// Leak Vacuum On操作
        /// 
        public bool LeakVacuumOnAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LEAK_VACUUM}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// Leak Vacuum Off操作
        /// 
        public bool LeakVacuumOffAction()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{LEAK_VACUUM}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        /// 
        /// FlowTest操作
        /// 
        public bool StartFlowTestAction()
        {
            if (!JudgeRunningState(LoaderCommonOperation.FlowTest))
            {
                _currentOperation = LoaderCommonOperation.FlowTest;
                _status = _flowTestRoutine.Start(false);               
                return true;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 停止  FlowTest操作
        /// 
        public bool StopFlowTestAction()
        {
            if (_currentOperation==LoaderCommonOperation.FlowTest)
            {
                _flowTestRoutine.Abort();
                _currentOperation = LoaderCommonOperation.None;
                _status = RState.End;
                return true;
            }
            else
            {
                return true;
            }
        }
        /// 
        /// 判定运行状态
        /// 
        /// 
        private bool JudgeRunningState(LoaderCommonOperation operation)
        {
            if (_status == RState.Running)
            {
                EV.PostAlarmLog($"{Module}.{Name}", eEvent.ERR_LOADER, $"{Module}.{Name} current execute {_currentOperation},cannot {operation}");
                return true;
            }
            return false;
        }
        #endregion
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateVariableValue(string variable, object value)
        {
            PropertyInfo property = CommonData.GetType().GetProperty(variable);
            if (property != null)
            {
                property.SetValue(CommonData, value);
            }
        }
        /// 
        /// 定时器
        /// 
        /// 
        public bool OnTimer()
        {
            if (_status == RState.Running)
            {
                if (_currentOperation != LoaderCommonOperation.None)
                {
                    IRoutine routine = GetCurrentRoutine(_currentOperation);
                    if (routine != null)
                    {
                        CheckRoutineState(routine, _currentOperation);
                    }
                    else
                    {
                        EndOperation(RState.End);
                    }
                }
            }
            return true;
        }
        /// 
        /// 获取当前操作对应的Routine
        /// 
        /// 
        /// 
        private IRoutine GetCurrentRoutine(LoaderCommonOperation currentOperation)
        {
            switch (currentOperation)
            {
                case LoaderCommonOperation.WaferHolderSideABClampOn:
                case LoaderCommonOperation.WaferHolderSideABClampOff:
                    return _sideClampRoutine;
                case LoaderCommonOperation.FlowTest:
                    return _flowTestRoutine;
                default:
                    return null;
            }
        }
        /// 
        /// 检验Routine状态
        /// 
        /// 
        /// 
        private void CheckRoutineState(IRoutine routine, LoaderCommonOperation currentOperation)
        {
            RState state = routine.Monitor();
            if (state == RState.End)
            {
                EndOperation(RState.End);
            }
            else if (state == RState.Failed || state == RState.Timeout)
            {
                LOG.WriteLog(eEvent.ERR_LOADER, $"{Module}.{Name}", $"{currentOperation} error");
                EndOperation(RState.Failed);
            }
        }
        /// 
        /// 结束操作
        /// 
        private void EndOperation(RState state)
        {
            _status = state;
            _currentOperation = LoaderCommonOperation.None;
        }
        public void ExportFlowLotTrackDatas(List flowDatas)
        {
            _flowDatas.Clear();
            _flowDatas = flowDatas;
        }
        #region 设备接口
        /// 
        /// 监控
        /// 
        public void Monitor()
        {
            
        }
        public void Reset()
        {
        }
        public void Terminate()
        {
        }
        #endregion
    }
}