using Common.Attributes;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.Json;
using TSMaster;
using static Common.Attributes.ATSCommandAttribute;

namespace TSMasterCAN
{
    /// <summary>
    /// 同星CAN驱动类
    /// </summary>
    [ATSCommand]
    [DeviceCategory("CAN卡驱动")]
    public class CAN
    {
        public static event Action ConnectEvent;
        public static event Action DisConnectEvent;
        public static bool ConnectFlag { get; set; } = false;

        /// <summary>
        /// 用于接收CAN报文的队列
        /// </summary>
        private static readonly Queue<TLIBCANFD> _receivedMessages = new Queue<TLIBCANFD>();
        private static readonly object _lock = new object(); // 线程安全锁

        /// <summary>
        /// 初始化CAN驱动
        /// </summary>
        /// <param name="ProjectName"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        [Browsable(false)]
        public static int Init(string ProjectName, string? filePath = null)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                return TsMasterApi.initialize_lib_tsmaster(ProjectName);
            }
            else
            {
                return TsMasterApi.initialize_lib_tsmaster_with_project(ProjectName, Path.GetFullPath(filePath));
            }
        }

        /// <summary>
        /// 释放CAN驱动
        /// </summary>
        [Browsable(false)]
        public static void Release()
        {
            TsMasterApi.finalize_lib_tsmaster();
        }

        public static int obj = 0;
        public static TCANFDQueueEvent_Win32 listener;
        [Browsable(false)]
        public static int RegisterListener(TCANFDQueueEvent_Win32 listenEvent)
        {
            listener = listenEvent;
            var re = TsMasterApi.tsapp_register_event_canfd(ref obj, listener);
           // Debug.Assert(re == 0);
            return re;
        }

        [Browsable(false)]
        public static int UnRegisterListener(TCANFDQueueEvent_Win32 listenEvent = null)
        {
            if (listenEvent is not null)
            {
                listener = listenEvent;
            }
            var re = TsMasterApi.tsapp_unregister_event_canfd(ref obj, listener);
            Debug.Assert(re == 0);
            return re;
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <returns></returns>
        public static int Connect()
        {
            var re = TsMasterApi.tsapp_connect();
            if (re == 0)
            {
                re = TsMasterApi.tscom_can_rbs_start();
                if (re == 0)
                {
                    ConnectFlag = true;
                    Task.Run(() => ConnectEvent?.Invoke());
                }
                else
                {
                    Debug.WriteLine($"CAN_RBS启动失败,错误代码：{re}");
                }
            }
            else
            {
                Debug.WriteLine($"CAN连接失败,错误代码：{re}");
                return re;
            }
            return re;
        }

        /// <summary>
        /// 断开
        /// </summary>
        /// <returns></returns>
        public static int DisConnect()
        {
            var re = TsMasterApi.tsapp_disconnect();
            if (re == 0)
            {
                ConnectFlag = false;
                Task.Run(() => DisConnectEvent?.Invoke());
            }
            else
            {
                Debug.WriteLine($"断开CAN连接失败,错误代码：{re}");
            }
            return re;
        }

        /// <summary>
        /// 加载DBC
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="channel"></param>
        /// <param name="databaseID"></param>
        /// <returns></returns>
        [Browsable(false)]
        public static int LoadDBC(string filePath, int[] channel, out uint databaseID)
        {
            databaseID = 0;

            var re = TsMasterApi.tsdb_load_can_db(Path.GetFullPath(filePath), string.Join(",", channel), ref databaseID);
            foreach (var item in channel)
            {
                DBCParse.parse(databaseID, item);
                DBCParse.rbs_parse(databaseID, item);
            }

            return re;
        }

        /// <summary>
        /// 卸载DBC
        /// </summary>
        /// <param name="databaseID"></param>
        /// <returns></returns>
        [Browsable(false)]
        public static int UnLoadDBC(uint? databaseID = null)
        {
            if (databaseID == null)
            {
                return TsMasterApi.tsdb_unload_can_dbs();
            }
            else
            {
                return TsMasterApi.tsdb_unload_can_db(databaseID.Value);
            }
        }

        /// <summary>
        /// 开始记录日志
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static int StartLogging(string filePath)
        {
            return TsMasterApi.tsapp_start_logging(Path.GetFullPath(filePath));
        }

        /// <summary>
        /// 结束记录日志
        /// </summary>
        /// <returns></returns>
        public static int StopLogging()
        {
            return TsMasterApi.tsapp_stop_logging();
        }

        /// <summary>
        /// 弹出通道映射窗口
        /// </summary>
        /// <param name="isWait"></param>
        /// <returns></returns>
        [Browsable(false)]
        public static int ShowChannelMappingWindow(bool isWait = false)
        {
            return TsMasterApi.tsapp_show_tsmaster_window("Hardware", isWait);
        }

        #region 信号值获取方法

        /// <summary>
        /// 获取信号值 (基于DBC)
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <returns>信号值</returns>
        public static double GetSignalValue(byte channel, string AMsgName, string ASgnName)
        {
            double value = double.NaN;
            var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
            if (find != null)
            {
                var re = TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
                if (re != 0)
                {
                    Debug.WriteLine($"GetSignalValue: 获取信号值失败, 错误代码: {re}, 消息: {AMsgName}, 信号: {ASgnName}");
                }
            }
            else
            {
                Debug.WriteLine($"GetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
            }
            return value;
        }

        /// <summary>
        /// 获取信号值 (基于DBC) - 带返回值
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <param name="value">输出信号值</param>
        /// <returns>TSMaster API 返回值</returns>
        [Browsable(false)]
        public static int GetSignalValue(byte channel, string AMsgName, string ASgnName, ref double value)
        {
            var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
            if (find != null)
            {
                return TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
            }
            else
            {
                Debug.WriteLine($"GetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
                return -1; // 假设 -1 为未找到定义的错误码
            }
        }

        /// <summary>
        /// 获取信号值 (基于已有的CANFD报文对象) - 已优化，无需用户传入 TLIBCANFD
        /// 此方法保留用于高级场景，但通常不推荐外部直接使用
        /// </summary>
        /// <param name="ACANFD">CANFD报文对象</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <param name="value">输出信号值</param>
        /// <returns>TSMaster API 返回值</returns>
        [Browsable(false)]
        public static int GetSignalValue(ref TLIBCANFD ACANFD, string AMsgName, string ASgnName, ref double value)
        {
            return TsMasterApi.tsdb_get_signal_value_canfd(ref ACANFD, AMsgName, ASgnName, ref value);
        }

        #endregion

        #region 信号值设置方法

        /// <summary>
        /// 设置信号值 (基于DBC)
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <param name="AValue">信号值</param>
        /// <param name="isSend">是否立即发送</param>
        /// <param name="sendPeriod">发送周期 (ms)，0表示单次发送</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static int SetSignalValue(byte channel, string AMsgName, string ASgnName, double AValue, bool isSend = false, float sendPeriod = 0)
        {
            var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
            if (find == null)
            {
                Debug.WriteLine($"SetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
                return -1; // 或抛出异常
            }
            find.ACANFD.FIdxChn = channel;
            var re = TsMasterApi.tsdb_set_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, AValue);
            Debug.Assert(re == 0);
            if (re != 0) throw new Exception($"设置信号值失败!返回代码{re}");
            if (re != 0) return re;
            if (isSend)
            {
                if (sendPeriod == 0)
                {
                    return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
                }
                else
                {
                    return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
                }
            }
            return 0;
        }

        /// <summary>
        /// 设置信号值 (基于DBC) - 仅发送报文
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="sendPeriod">发送周期 (ms)，0表示单次发送</param>
        /// <returns></returns>
        public static int SetSignalValue(APP_CHANNEL channel, string AMsgName, float sendPeriod = 0)
        {
            var find = DBCParse.MsgDatabase[(byte)channel].FirstOrDefault(s => s.msg_name == AMsgName);
            if (find == null)
            {
                Debug.WriteLine($"SetSignalValue: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
                return -1; // 或抛出异常
            }
            find.ACANFD.FIdxChn = (byte)channel;
            if (sendPeriod == 0)
            {
                return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
            }
            else
            {
                return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
            }
        }

        #endregion

        #region 报文发送方法

        /// <summary>
        /// 发送自定义报文 (基于 TLIBCANFD 对象) - 已优化，内部使用，外部不直接暴露
        /// </summary>
        /// <param name="msg">CANFD报文对象</param>
        /// <returns></returns>
        [Browsable(false)]
        public static int SetMsg(TLIBCANFD msg)
        {
            return TsMasterApi.tsapp_transmit_canfd_async(ref msg);
        }

        /// <summary>
        /// 设置报文数据 (在DBC缓存中)
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="ID">报文ID</param>
        /// <param name="bytes">报文数据数组</param>
        public static void SetMsg(APP_CHANNEL channel, int ID, byte[] bytes)
        {
            var find = DBCParse.MsgDatabase[(byte)channel].FirstOrDefault(s => s.ACANFD.FIdentifier == ID);
            if (find != null)
            {
                Array.Copy(bytes, 0, find.ACANFD.FData, 0, Math.Min(bytes.Length, find.ACANFD.FData.Length));
            }
            else
            {
                Debug.WriteLine($"SetMsg: 未找到报文定义, ID: 0x{ID:X}, 通道: {channel}");
            }
        }

        /// <summary>
        /// 发送自定义报文
        /// </summary>
        /// <param name="AIdxChn">通道</param>
        /// <param name="AID">报文ID</param>
        /// <param name="AIsTx">是否为发送帧</param>
        /// <param name="AIsExt">是否为扩展帧</param>
        /// <param name="AIsRemote">是否为远程帧</param>
        /// <param name="ADLC">数据长度</param>
        /// <param name="ADataArray">数据数组</param>
        /// <param name="AIsFD">是否为FD帧</param>
        /// <param name="AIsBRS">是否为BRS</param>
        /// <param name="isUpdateDBCDatabase">是否更新DBC数据库</param>
        /// <param name="sendPeriod">发送周期 (ms)</param>
        /// <returns></returns>
        public static int SendMsg(APP_CHANNEL AIdxChn, int AID, bool AIsTx, bool AIsExt,
            bool AIsRemote, byte ADLC, byte[] ADataArray, bool AIsFD = true, bool AIsBRS = false,
            bool isUpdateDBCDatabase = false, float sendPeriod = 0)
        {
            var send = new TLIBCANFD
            {
                FIdxChn = (byte)AIdxChn,
                FProperties = 0,
                FIdentifier = AID,
                FDLC = ADLC,
                FTimeUS = 0uL,
                FData = new byte[64],
                FFDProperties = 0,
                FIsTx = AIsTx,
                FIsError = false,
                FIsExt = AIsExt,
                FIsRemote = AIsRemote,
                FIsFD = AIsFD,
                FIsBRS = AIsBRS
            };
            int length = Math.Min(ADataArray.Length, 64);
            Array.Copy(ADataArray, 0, send.FData, 0, length);
            int re;
            if (sendPeriod == 0)
            {
                re = TsMasterApi.tsapp_transmit_canfd_async(ref send);
            }
            else
            {
                re = TsMasterApi.tsapp_add_cyclic_msg_canfd(ref send, sendPeriod);
            }

            if (isUpdateDBCDatabase)
            {
                var find = DBCParse.MsgDatabase[(byte)AIdxChn].FirstOrDefault(s => s.ACANFD.FIdentifier == send.FIdentifier);
                if (find != null)
                {
                    Array.Copy(send.FData, 0, find.ACANFD.FData, 0, Math.Min(ADataArray.Length, find.ACANFD.FData.Length));
                }
            }
            return re;
        }

        /// <summary>
        /// 添加循环发送报文
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="sendPeriod">发送周期 (ms)</param>
        /// <returns></returns>
        public static int AddCyclicMsg(byte channel, string AMsgName, float sendPeriod)
        {
            var find = DBCParse.MsgDatabase[channel].FirstOrDefault(s => s.msg_name == AMsgName);
            if (find == null)
            {
                Debug.WriteLine($"AddCyclicMsg: 未找到消息定义, 消息: {AMsgName}, 通道: {channel}");
                return -1; // 或抛出异常
            }
            find.ACANFD.FIdxChn = channel;
            return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
        }

        /// <summary>
        /// 清除循环发送的报文
        /// </summary>
        /// <returns></returns>
        public static int DeleteCyclicMsgs()
        {
            return TsMasterApi.tsapp_delete_cyclic_msgs();
        }

        #endregion

        #region 接收报文和信号值方法 (新增)

        /// <summary>
        /// 符合 TCANFDQueueEvent_Win32 委托签名的回调方法
        /// </summary>
        /// <param name="AObj">对象句柄</param>
        /// <param name="AData">接收到的 CANFD 报文</param>
        private static void OnCanFdMessageReceived(ref int AObj, ref TLIBCANFD AData)
        {
            // 将接收到的报文加入队列
            lock (_lock)
            {
                // 为防止队列无限增长，可以添加一个简单的大小限制
                if (_receivedMessages.Count < 10000) // 例如，限制队列最大10000个报文
                {
                    _receivedMessages.Enqueue(AData);
                }
                // 可选：记录队列溢出
                else
                {
                    Debug.WriteLine("接收队列已满，丢弃新报文。");
                }
            }
        }

        /// <summary>
        /// 注册接收报文的监听器 (需要在连接前调用)
        /// </summary>
        /// <returns></returns>
        public static int RegisterReceiveListener()
        {
            return RegisterListener(OnCanFdMessageReceived);
        }

        /// <summary>
        /// 尝试获取一个接收到的CANFD报文
        /// </summary>
        /// <param name="receivedMsg">输出报文对象</param>
        /// <returns>如果队列不为空则返回true，否则返回false</returns>
        public static bool TryGetReceivedMessage(out TLIBCANFD receivedMsg)
        {
            lock (_lock)
            {
                if (_receivedMessages.Count > 0)
                {
                    receivedMsg = _receivedMessages.Dequeue();
                    return true;
                }
                else
                {
                    receivedMsg = new TLIBCANFD(); // 返回默认值
                    return false;
                }
            }
        }

        /// <summary>
        /// 获取接收队列中的报文数量
        /// </summary>
        /// <returns></returns>
        public static int GetReceivedMessageCount()
        {
            lock (_lock)
            {
                return _receivedMessages.Count;
            }
        }

        /// <summary>
        /// 清空接收队列
        /// </summary>
        public static void ClearReceivedMessages()
        {
            lock (_lock)
            {
                _receivedMessages.Clear();
            }
        }

        /// <summary>
        /// 从接收到的报文中解析信号值 (基于DBC)
        /// </summary>
        /// <param name="receivedMsg">接收到的报文</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <returns>信号值</returns>
        public static double GetSignalValueFromReceivedMessage(TLIBCANFD receivedMsg, string AMsgName, string ASgnName)
        {
            double value = double.NaN;
            var re = TsMasterApi.tsdb_get_signal_value_canfd(ref receivedMsg, AMsgName, ASgnName, ref value);
            if (re != 0)
            {
                Debug.WriteLine($"GetSignalValueFromReceivedMessage: 从报文中解析信号值失败, 错误代码: {re}, 消息: {AMsgName}, 信号: {ASgnName}");
            }
            return value;
        }

        /// <summary>
        /// 从接收到的报文中解析信号值 (基于DBC) - 便捷方法
        /// 该方法会先尝试获取一个报文，然后解析信号值
        /// </summary>
        /// <param name="channel">期望的通道 (用于过滤)</param>
        /// <param name="expectedID">期望的报文ID (用于过滤, 0 表示不过滤)</param>
        /// <param name="AMsgName">消息名称</param>
        /// <param name="ASgnName">信号名称</param>
        /// <returns>信号值，如果获取失败则返回 NaN</returns>
        public static double GetSignalValueFromReceivedMessage(byte channel, uint expectedID, string AMsgName, string ASgnName)
        {
            var value = double.NaN;
            // 创建一个临时队列来存放不符合条件的报文
            var tempQueue = new Queue<TLIBCANFD>();

            lock (_lock)
            {
                while (_receivedMessages.Count > 0)
                {
                    var msg = _receivedMessages.Dequeue();

                    // 检查是否符合条件
                    if (msg.FIdxChn == channel && (expectedID == 0 || (uint)msg.FIdentifier == expectedID))
                    {
                        // 符合条件，尝试解析信号值
                        var re = TsMasterApi.tsdb_get_signal_value_canfd(ref msg, AMsgName, ASgnName, ref value);
                        if (re == 0)
                        {
                            // 解析成功，将 tempQueue 中的报文放回主队列
                            while (tempQueue.Count > 0)
                            {
                                _receivedMessages.Enqueue(tempQueue.Dequeue());
                            }
                            return value; // 返回解析出的值
                        }
                        else
                        {
                            Debug.WriteLine($"GetSignalValueFromReceivedMessage: 从报文中解析信号值失败, 错误代码: {re}, 消息: {AMsgName}, 信号: {ASgnName}");
                        }
                    }

                    // 不符合条件或解析失败，放入临时队列
                    tempQueue.Enqueue(msg);
                }

                // 将临时队列中的所有报文放回主队列
                while (tempQueue.Count > 0)
                {
                    _receivedMessages.Enqueue(tempQueue.Dequeue());
                }
            }

            return value; // 返回 NaN
        }

        #endregion

        /// <summary>
        /// 获取错误提示
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <returns></returns>
        public static string GetErrorDescription(int errorCode)
        {
            IntPtr ADesc = IntPtr.Zero;
            TsMasterApi.tsapp_get_error_description(errorCode, ref ADesc);

            if (ADesc == IntPtr.Zero) return $"未知错误代码: {errorCode}";

            string? description = Marshal.PtrToStringAnsi(ADesc);

            return description ?? $"未知错误代码: {errorCode}";
        }

        #region CANFD转换相关方法

        /// <summary>
        /// CANFD转CAN
        /// 注意：如果CANFD报文长度超过8字节，转换时会截断数据。
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>CAN消息</returns>
        public static TLIBCAN CANFDToCAN(TLIBCANFD canfdMsg)
        {
            TLIBCAN canMsg = new TLIBCAN
            {
                FIdxChn = canfdMsg.FIdxChn,
                FProperties = canfdMsg.FProperties,
                FIdentifier = canfdMsg.FIdentifier,
                FData = new byte[8], // CAN标准数据长度
                FTimeUS = canfdMsg.FTimeUS, // 时间戳保持不变
                FDLC = canfdMsg.FDLC > 8 ? (byte)8 : canfdMsg.FDLC, // DLC限制在8以内
                FIsTx = canfdMsg.FIsTx,
                FIsError = canfdMsg.FIsError,
                FIsExt = canfdMsg.FIsExt,
                FIsRemote = canfdMsg.FIsRemote
            };
            // 复制数据，只取前8字节
            Array.Copy(canfdMsg.FData, 0, canMsg.FData, 0, Math.Min(8, canfdMsg.FData.Length));
            return canMsg;
        }

        /// <summary>
        /// CAN转CANFD
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <returns>CANFD消息</returns>
        public static TLIBCANFD CANToCANFD(TLIBCAN canMsg)
        {
            TLIBCANFD canfdMsg = new TLIBCANFD
            {
                FIdxChn = canMsg.FIdxChn,
                FProperties = canMsg.FProperties, // 保留原始属性
                FIdentifier = canMsg.FIdentifier,
                FData = new byte[64], // CANFD最大数据长度
                FTimeUS = canMsg.FTimeUS,
                FDLC = canMsg.FDLC,
                FFDProperties = 0, // 新的CANFD报文，FD属性初始化为0
                FIsTx = canMsg.FIsTx,
                FIsError = canMsg.FIsError,
                FIsExt = canMsg.FIsExt,
                FIsRemote = canMsg.FIsRemote,
                FIsFD = false, // 从CAN转换，明确设置为非FD
                FIsBRS = false // 从CAN转换，明确设置为不支持BRS
            };
            // 复制数据
            Array.Copy(canMsg.FData, 0, canfdMsg.FData, 0, Math.Min(64, canMsg.FData.Length));
            return canfdMsg;
        }

        #endregion

        #region CANFD报文属性获取方法

        /// <summary>
        /// 获取CANFD报文内容
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>报文数据数组，长度为FDLC指定的长度</returns>
        public static byte[] GetCANFDMsgContent(TLIBCANFD canfdMsg)
        {
            byte[] content = new byte[Math.Min(canfdMsg.FData.Length, canfdMsg.FDLC)];
            Array.Copy(canfdMsg.FData, 0, content, 0, content.Length);
            return content;
        }

        /// <summary>
        /// 获取CANFD报文时间戳 (微秒)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>时间戳 (微秒)</returns>
        public static ulong GetCANFDMsgTimestamp(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FTimeUS;
        }

        /// <summary>
        /// 获取CANFD报文数据长度 (DLC)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>数据长度 (DLC)</returns>
        public static byte GetCANFDMsgDataLength(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FDLC;
        }

        /// <summary>
        /// 获取CANFD报文是否为错误帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为错误帧</returns>
        public static bool GetCANFDMsgIsError(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsError;
        }

        /// <summary>
        /// 获取CANFD报文通道
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>通道号</returns>
        public static byte GetCANFDMsgChannel(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIdxChn;
        }

        /// <summary>
        /// 获取CANFD报文FD相关属性 (具体含义需参考TSMaster文档)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>FD属性</returns>
        public static uint GetCANFDMsgFDProperties(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FFDProperties;
        }

        /// <summary>
        /// 获取CANFD报文基础属性 (具体含义需参考TSMaster文档)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>基础属性</returns>
        public static uint GetCANFDMsgProperties(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FProperties;
        }

        /// <summary>
        /// 获取CANFD报文标识符 (ID)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>标识符 (ID)</returns>
        public static uint GetCANFDMsgIdentifier(ref TLIBCANFD canfdMsg)
        {
            return (uint)canfdMsg.FIdentifier;
        }

        /// <summary>
        /// 获取CANFD报文是否为FD帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为FD帧</returns>
        public static bool GetCANFDMsgIsFD(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsFD;
        }

        /// <summary>
        /// 获取CANFD报文是否为远程帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为远程帧</returns>
        public static bool GetCANFDMsgIsRemote(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsRemote;
        }

        /// <summary>
        /// 获取CANFD报文是否为扩展帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为扩展帧</returns>
        public static bool GetCANFDMsgIsExt(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsExt;
        }

        /// <summary>
        /// 获取CANFD报文是否为BRS (Bit Rate Switch)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为BRS</returns>
        public static bool GetCANFDMsgIsBRS(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsBRS;
        }

        /// <summary>
        /// 获取CANFD报文是否为发送帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为发送帧</returns>
        public static bool GetCANFDMsgIsTx(ref TLIBCANFD canfdMsg)
        {
            return canfdMsg.FIsTx;
        }

        /// <summary>
        /// 获取CANFD报文是否为ESI (Error State Indicator)
        /// 注意：此API接口可能无法直接从TLIBCANFD结构获取ESI值。
        /// ESI通常由总线决定，接收时反映发送节点的错误状态。
        /// 当前实现返回FFDProperties的最低位，但这可能不准确。
        /// 实际使用中可能需要通过其他方式或API获取。
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <returns>是否为ESI (当前实现仅供参考)</returns>
        public static bool GetCANFDMsgIsESI(ref TLIBCANFD canfdMsg)
        {
            return (canfdMsg.FFDProperties & 0x01) != 0; // 警告：此实现可能不正确
        }

        #endregion

        #region CANFD报文设置方法

        /// <summary>
        /// 设置CANFD报文内容
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="data">要设置的数据</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgContent(ref TLIBCANFD canfdMsg, byte[] data)
        {
            if (data == null || data.Length == 0)
                return -1; // 错误代码

            int length = Math.Min(data.Length, canfdMsg.FData.Length);
            Array.Copy(data, 0, canfdMsg.FData, 0, length);
            canfdMsg.FDLC = (byte)length; // 同时更新DLC
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文时间戳 (微秒)
        /// 注意：此时间戳通常由硬件/驱动在接收时设置，发送时设置可能无效或有特殊用途。
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="timestamp">时间戳 (微秒)</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgTimestamp(ref TLIBCANFD canfdMsg, ulong timestamp)
        {
            canfdMsg.FTimeUS = timestamp;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文数据长度 (DLC)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="length">数据长度 (DLC)</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgDataLength(ref TLIBCANFD canfdMsg, byte length)
        {
            if (length > canfdMsg.FData.Length)
                return -1; // 错误代码，长度超出数组大小

            canfdMsg.FDLC = length;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为错误帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isError">是否为错误帧</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsError(ref TLIBCANFD canfdMsg, bool isError)
        {
            canfdMsg.FIsError = isError;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文通道
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="channel">通道号</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgChannel(ref TLIBCANFD canfdMsg, byte channel)
        {
            canfdMsg.FIdxChn = channel;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文FD相关属性
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="fdProperties">FD属性</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgFDProperties(ref TLIBCANFD canfdMsg, uint fdProperties)
        {
            canfdMsg.FFDProperties = (byte)fdProperties;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文基础属性
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="properties">基础属性</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgProperties(ref TLIBCANFD canfdMsg, uint properties)
        {
            canfdMsg.FProperties = (byte)properties;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文标识符 (ID)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="identifier">标识符 (ID)</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIdentifier(ref TLIBCANFD canfdMsg, uint identifier)
        {
            canfdMsg.FIdentifier = (int)identifier;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为FD帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isFD">是否为FD帧</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsFD(ref TLIBCANFD canfdMsg, bool isFD)
        {
            canfdMsg.FIsFD = isFD;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为远程帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isRemote">是否为远程帧</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsRemote(ref TLIBCANFD canfdMsg, bool isRemote)
        {
            canfdMsg.FIsRemote = isRemote;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为扩展帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isExt">是否为扩展帧</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsExt(ref TLIBCANFD canfdMsg, bool isExt)
        {
            canfdMsg.FIsExt = isExt;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为BRS (Bit Rate Switch)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isBRS">是否为BRS</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsBRS(ref TLIBCANFD canfdMsg, bool isBRS)
        {
            canfdMsg.FIsBRS = isBRS;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为发送帧
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isTx">是否为发送帧</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsTx(ref TLIBCANFD canfdMsg, bool isTx)
        {
            canfdMsg.FIsTx = isTx;
            return 0;
        }

        /// <summary>
        /// 设置CANFD报文是否为ESI (Error State Indicator)
        /// 注意：此API接口可能无法直接设置TLIBCANFD结构中的ESI值。
        /// ESI通常由硬件根据发送节点的错误状态自动设置。
        /// 当前实现通过操作FFDProperties的最低位来模拟，但这可能无效或不正确。
        /// 实际使用中可能无法或不应通过这种方式设置。
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="isESI">是否为ESI (当前实现仅供参考，可能无效)</param>
        /// <returns>设置结果 (0为成功)</returns>
        public static int SetCANFDMsgIsESI(ref TLIBCANFD canfdMsg, bool isESI)
        {
            byte mask = 0x01; // 最低位

            if (isESI)
                canfdMsg.FFDProperties |= mask; // 设置最低位
            else
                canfdMsg.FFDProperties &= (byte)~mask; // 清除最低位 (注意：~mask 会得到 -2，所以需要强制转换为 byte)

            return 0;
        }

        #endregion
        /// <summary>
        /// 获取CANFD报文指定字节的指定位的值 (0 或 1)
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="byteIndex">字节索引 (0-63 for CANFD)</param>
        /// <param name="bitIndex">位索引 (0-7)</param>
        /// <returns>位的值 (0 或 1)，如果索引无效则返回 -1</returns>
        public static int GetCANFDMsgBitValue(ref TLIBCANFD canfdMsg, int byteIndex, int bitIndex)
        {
            if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length || bitIndex < 0 || bitIndex > 7)
            {
                Debug.WriteLine($"GetCANFDMsgBitValue: Invalid index - byteIndex: {byteIndex}, bitIndex: {bitIndex}");
                return -1; // 或者抛出异常
            }
            byte mask = (byte)(1 << bitIndex);
            return (canfdMsg.FData[byteIndex] & mask) != 0 ? 1 : 0;
        }

        /// <summary>
        /// 设置CANFD报文指定字节的指定位的值
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="byteIndex">字节索引 (0-63 for CANFD)</param>
        /// <param name="bitIndex">位索引 (0-7)</param>
        /// <param name="value">要设置的值 (0 或 1)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int SetCANFDMsgBitValue(ref TLIBCANFD canfdMsg, int byteIndex, int bitIndex, int value)
        {
            if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length || bitIndex < 0 || bitIndex > 7 || (value != 0 && value != 1))
            {
                Debug.WriteLine($"SetCANFDMsgBitValue: Invalid input - byteIndex: {byteIndex}, bitIndex: {bitIndex}, value: {value}");
                return -1; // 或者抛出异常
            }
            byte mask = (byte)(1 << bitIndex);
            if (value == 1)
            {
                canfdMsg.FData[byteIndex] |= mask; // 设置该位
            }
            else
            {
                canfdMsg.FData[byteIndex] &= (byte)~mask; // 清除该位
            }
            return 0;
        }

        /// <summary>
        /// 对CANFD报文指定字节执行按位与(&)操作
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="byteIndex">字节索引 (0-63 for CANFD)</param>
        /// <param name="mask">要与的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseAndCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseAndCANFDMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canfdMsg.FData[byteIndex] &= mask;
            return 0;
        }

        /// <summary>
        /// 对CANFD报文指定字节执行按位或(|)操作
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="byteIndex">字节索引 (0-63 for CANFD)</param>
        /// <param name="mask">要或的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseOrCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseOrCANFDMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canfdMsg.FData[byteIndex] |= mask;
            return 0;
        }

        /// <summary>
        /// 对CANFD报文指定字节执行按位异或(^)操作
        /// </summary>
        /// <param name="canfdMsg">CANFD消息</param>
        /// <param name="byteIndex">字节索引 (0-63 for CANFD)</param>
        /// <param name="mask">要异或的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseXorCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseXorCANFDMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canfdMsg.FData[byteIndex] ^= mask;
            return 0;
        }


        #region CAN Message Handling (为CAN添加位操作方法)

        /// <summary>
        /// 获取CAN报文指定字节的指定位的值 (0 或 1)
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <param name="byteIndex">字节索引 (0-7 for CAN)</param>
        /// <param name="bitIndex">位索引 (0-7)</param>
        /// <returns>位的值 (0 或 1)，如果索引无效则返回 -1</returns>
        public static int GetCANMsgBitValue(ref TLIBCAN canMsg, int byteIndex, int bitIndex)
        {
            if (byteIndex < 0 || byteIndex >= canMsg.FData.Length || bitIndex < 0 || bitIndex > 7)
            {
                Debug.WriteLine($"GetCANMsgBitValue: Invalid index - byteIndex: {byteIndex}, bitIndex: {bitIndex}");
                return -1;
            }
            byte mask = (byte)(1 << bitIndex);
            return (canMsg.FData[byteIndex] & mask) != 0 ? 1 : 0;
        }

        /// <summary>
        /// 设置CAN报文指定字节的指定位的值
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <param name="byteIndex">字节索引 (0-7 for CAN)</param>
        /// <param name="bitIndex">位索引 (0-7)</param>
        /// <param name="value">要设置的值 (0 或 1)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int SetCANMsgBitValue(ref TLIBCAN canMsg, int byteIndex, int bitIndex, int value)
        {
            if (byteIndex < 0 || byteIndex >= canMsg.FData.Length || bitIndex < 0 || bitIndex > 7 || (value != 0 && value != 1))
            {
                Debug.WriteLine($"SetCANMsgBitValue: Invalid input - byteIndex: {byteIndex}, bitIndex: {bitIndex}, value: {value}");
                return -1;
            }
            byte mask = (byte)(1 << bitIndex);
            if (value == 1)
            {
                canMsg.FData[byteIndex] |= mask;
            }
            else
            {
                canMsg.FData[byteIndex] &= (byte)~mask;
            }
            return 0;
        }

        /// <summary>
        /// 对CAN报文指定字节执行按位与(&)操作
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <param name="byteIndex">字节索引 (0-7 for CAN)</param>
        /// <param name="mask">要与的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseAndCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseAndCANMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canMsg.FData[byteIndex] &= mask;
            return 0;
        }

        /// <summary>
        /// 对CAN报文指定字节执行按位或(|)操作
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <param name="byteIndex">字节索引 (0-7 for CAN)</param>
        /// <param name="mask">要或的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseOrCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseOrCANMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canMsg.FData[byteIndex] |= mask;
            return 0;
        }

        /// <summary>
        /// 对CAN报文指定字节执行按位异或(^)操作
        /// </summary>
        /// <param name="canMsg">CAN消息</param>
        /// <param name="byteIndex">字节索引 (0-7 for CAN)</param>
        /// <param name="mask">要异或的掩码值 (byte)</param>
        /// <returns>操作结果 (0为成功, -1为失败)</returns>
        public static int BitwiseXorCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
        {
            if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
            {
                Debug.WriteLine($"BitwiseXorCANMsgByte: Invalid byteIndex - {byteIndex}");
                return -1;
            }
            canMsg.FData[byteIndex] ^= mask;
            return 0;
        }

        #endregion
    }
}