//! 主站配置管理
//!
//! 统一管理所有通信配置，包括周期、网络传输、PDO、互斥锁保护等。
//! 通过 master.config() 获取实例。

use crate::utils::ffi;
use crate::master::core::EtherCATMaster;

/// 主站配置类 - 统一管理所有通信配置
///
/// 包含:
/// - 周期配置 (loop_cycle)
/// - 网络传输 (frame_high_priority, use_udp, vlan_id, vlan_priority)
/// - PDO 配置 (overlapping_groups, filter_threshold)
/// - 互斥锁保护 (mutex_protection)
/// - 看门狗配置 (process_data_watchdog_ms, pdi_watchdog_ms)
/// - 帧重复 (frame_repeat_count)
/// - 自适应超时 (adaptive_timeout_enabled)
/// - 邮箱配置 (mailbox_timeout, mailbox_retries)
///
/// # 示例
/// ```no_run
/// let master = EtherCATMaster::new().unwrap();
/// let config = master.config();
/// config.set_loop_cycle(1_000_000); // 1ms
/// config.set_frame_high_priority(true);
/// config.set_mutex_protection(false);
/// config.set_mailbox_timeout(5000); // 5秒
/// config.set_mailbox_retries(3);
/// ```
pub struct MasterConfig<'a> {
    master: &'a EtherCATMaster,
}

impl<'a> MasterConfig<'a> {
    /// 创建主站配置实例 (内部使用, 通过 master.config() 获取)
    pub(crate) fn new(master: &'a EtherCATMaster) -> Self {
        Self { master }
    }

    // ===================== 周期配置 =====================

    /// 获取 PDO 交换周期时间（纳秒）
    pub fn loop_cycle(&self) -> u32 {
        // 通过 GetMasterStateCache 读取 主站状态中的 cycle_time_ns 字段
        // 由于无法直接读取 主站状态结构, 使用 DLL 提供的接口
        // 这里使用 GetTimingMode 作为替代, 但实际周期通过 SetMasterLoopCycleTime 设置
        unsafe { ffi::GetTimingMode(self.master.index()) }
    }

    /// 设置 PDO 交换周期时间（纳秒）
    /// Windows 系统建议不低于 125,000ns (125us)
    pub fn set_loop_cycle(&self, time_ns: u32) {
        unsafe { ffi::SetMasterLoopCycleTime(self.master.index(), time_ns) };
    }

    // ===================== 网络传输 =====================

    /// 获取帧高优先级配置
    ///
    /// OS 层帧优先级提升 (Linux: SO_PRIORITY, Windows: 线程优先级)
    pub fn frame_high_priority(&self) -> bool {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return false; }
        // 主站状态结构中 frame_high_priority 偏移量由 C 层定义
        // 使用安全的方式读取: 偏移位置已知为固定偏移
        // 注意: 此处依赖主站状态结构的 ABI 布局, 需要与 C 层保持同步
        unsafe {
            let byte_ptr = ptr as *const u8;
            // frame_high_priority 是 主站状态中的一个 u8 字段
            // 通过 DLL 状态指针直接读取
            *byte_ptr.add(OFFSET_FRAME_HIGH_PRIORITY) != 0
        }
    }

    /// 设置帧高优先级配置（默认启用）
    pub fn set_frame_high_priority(&self, value: bool) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_FRAME_HIGH_PRIORITY) = if value { 1 } else { 0 };
        }
    }

    /// 获取 UDP 帧模式 (ETG.1500 5.3.7)
    pub fn use_udp(&self) -> bool {
        (unsafe { ffi::GetUdpMode(self.master.index()) }) != 0
    }

    /// 设置 UDP 帧模式 - 支持运行时切换
    /// 启用后，EtherCAT 数据报将通过 UDP/IP 传输
    pub fn set_use_udp(&self, value: bool) {
        unsafe { ffi::SetUdpMode(self.master.index(), if value { 1 } else { 0 }) };
    }

    /// 检查 UDP 模式是否可用（双 Socket 是否初始化成功）
    pub fn is_udp_available(&self) -> bool {
        (unsafe { ffi::IsUdpAvailable(self.master.index()) }) != 0
    }

    /// 获取 VLAN ID (IEEE 802.1Q)
    /// 范围: 0-4095, 0 = 禁用 VLAN 标签
    pub fn vlan_id(&self) -> u16 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 0; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u16::from_le_bytes([
                *byte_ptr.add(OFFSET_VLAN_ID),
                *byte_ptr.add(OFFSET_VLAN_ID + 1),
            ])
        }
    }

    /// 设置 VLAN ID (IEEE 802.1Q)
    /// 范围: 0-4095, 0 = 禁用 VLAN 标签
    /// 仅 WDK 驱动模式下生效, 需要在 SetNetwork 之前设置
    pub fn set_vlan_id(&self, value: u16) {
        if value > 4095 { return; }
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = value.to_le_bytes();
            *byte_ptr.add(OFFSET_VLAN_ID) = bytes[0];
            *byte_ptr.add(OFFSET_VLAN_ID + 1) = bytes[1];
        }
    }

    /// 获取 VLAN 优先级 (PCP, IEEE 802.1Q)
    /// 范围: 0-7, 7 为最高优先级
    pub fn vlan_priority(&self) -> u8 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 0; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_VLAN_PRIORITY)
        }
    }

    /// 设置 VLAN 优先级 (PCP, IEEE 802.1Q)
    /// 范围: 0-7, 7 为最高优先级
    pub fn set_vlan_priority(&self, value: u8) {
        if value > 7 { return; }
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_VLAN_PRIORITY) = value;
        }
    }

    // ===================== PDO 配置 =====================

    /// 获取 PDO 通信优化开关 (Overlapping Groups)
    pub fn overlapping_groups(&self) -> bool {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return false; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_OVERLAPPING_GROUPS) != 0
        }
    }

    /// 设置 PDO 通信优化开关 (Overlapping Groups)
    /// 仅在 INIT 或 PRE_OP 状态下设置
    pub fn set_overlapping_groups(&self, value: bool) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_OVERLAPPING_GROUPS) = if value { 1 } else { 0 };
        }
    }

    /// 获取 Packed PDO 映射模式
    pub fn packed_mode(&self) -> bool {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return false; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_PACKED_MODE) != 0
        }
    }

    /// 设置 Packed PDO 映射模式 (0=字节对齐默认, 1=bit紧密映射)
    /// 仅在 INIT 或 PRE_OP 状态下设置
    pub fn set_packed_mode(&self, value: bool) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_PACKED_MODE) = if value { 1 } else { 0 };
        }
    }

    /// 获取判断滤波阈值
    pub fn filter_threshold(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 3; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_FILTER_THRESHOLD),
                *byte_ptr.add(OFFSET_FILTER_THRESHOLD + 1),
                *byte_ptr.add(OFFSET_FILTER_THRESHOLD + 2),
                *byte_ptr.add(OFFSET_FILTER_THRESHOLD + 3),
            ])
        }
    }

    /// 设置判断滤波阈值 (默认值为 3)
    pub fn set_filter_threshold(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = value.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_FILTER_THRESHOLD + i) = bytes[i];
            }
        }
    }

    // ===================== 帧重复 (ETG.1500 5.4.3) =====================

    /// 获取帧重复次数
    /// 1 = 禁用, 2-3 = 每周期发送 N 次相同 PDO 帧
    pub fn frame_repeat_count(&self) -> u8 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 1; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_FRAME_REPEAT_COUNT)
        }
    }

    /// 设置帧重复次数 (1-3)
    pub fn set_frame_repeat_count(&self, value: u8) {
        if value < 1 || value > 3 { return; }
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_FRAME_REPEAT_COUNT) = value;
        }
    }

    // ===================== 互斥锁保护 =====================

    /// 获取互斥锁保护状态
    pub fn mutex_protection(&self) -> bool {
        (unsafe { ffi::GetMutexProtection(self.master.index()) }) != 0
    }

    /// 设置互斥锁保护
    /// 启用后（默认）: 自动互斥锁保护，确保线程安全
    /// 关闭后: 禁用自动互斥锁保护，由用户自行管理线程安全
    pub fn set_mutex_protection(&self, value: bool) {
        unsafe { ffi::SetMutexProtection(self.master.index(), if value { 1 } else { 0 }) };
    }

    // ===================== 看门狗配置 (ETG.1000.4) =====================

    /// 获取过程数据看门狗超时（毫秒）
    pub fn process_data_watchdog_ms(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 0; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u16::from_le_bytes([
                *byte_ptr.add(OFFSET_WD_PD_TIMEOUT_MS),
                *byte_ptr.add(OFFSET_WD_PD_TIMEOUT_MS + 1),
            ]) as u32
        }
    }

    /// 设置过程数据看门狗超时（毫秒）
    /// 0 = 使用从站默认值（通常 100ms）
    pub fn set_process_data_watchdog_ms(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        let clamped = value.min(6553) as u16;
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = clamped.to_le_bytes();
            *byte_ptr.add(OFFSET_WD_PD_TIMEOUT_MS) = bytes[0];
            *byte_ptr.add(OFFSET_WD_PD_TIMEOUT_MS + 1) = bytes[1];
        }
    }

    /// 获取 PDI 看门狗超时（毫秒）
    pub fn pdi_watchdog_ms(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 0; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u16::from_le_bytes([
                *byte_ptr.add(OFFSET_WD_PDI_TIMEOUT_MS),
                *byte_ptr.add(OFFSET_WD_PDI_TIMEOUT_MS + 1),
            ]) as u32
        }
    }

    /// 设置 PDI 看门狗超时（毫秒）
    /// 0 = 使用从站默认值（通常 100ms）
    pub fn set_pdi_watchdog_ms(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        let clamped = value.min(6553) as u16;
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = clamped.to_le_bytes();
            *byte_ptr.add(OFFSET_WD_PDI_TIMEOUT_MS) = bytes[0];
            *byte_ptr.add(OFFSET_WD_PDI_TIMEOUT_MS + 1) = bytes[1];
        }
    }

    // ===================== 自适应超时 =====================

    /// 获取自适应超时功能状态（默认启用）
    /// 启用后，多次采样实际网络 RTT 取最大值
    pub fn adaptive_timeout_enabled(&self) -> bool {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return false; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_ADAPTIVE_TIMEOUT_ENABLED) != 0
        }
    }

    /// 设置自适应超时功能
    pub fn set_adaptive_timeout_enabled(&self, value: bool) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_ADAPTIVE_TIMEOUT_ENABLED) = if value { 1 } else { 0 };
        }
    }

    // ===================== 状态转换超时配置 (ETG.1020) =====================

    /// INIT->PREOP 状态转换超时 (毫秒, ETG.1020 默认 3000)
    pub fn timeout_init_to_preop(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 3000; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_TIMEOUT_INIT_TO_PREOP),
                *byte_ptr.add(OFFSET_TIMEOUT_INIT_TO_PREOP + 1),
                *byte_ptr.add(OFFSET_TIMEOUT_INIT_TO_PREOP + 2),
                *byte_ptr.add(OFFSET_TIMEOUT_INIT_TO_PREOP + 3),
            ])
        }
    }

    /// 设置 INIT->PREOP 状态转换超时 (毫秒)
    pub fn set_timeout_init_to_preop(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = value.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_TIMEOUT_INIT_TO_PREOP + i) = bytes[i];
            }
        }
    }

    /// PREOP->SAFEOP 状态转换超时 (毫秒, ETG.1020 默认 10000)
    pub fn timeout_preop_to_safeop(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 10000; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_TIMEOUT_PREOP_TO_SAFEOP),
                *byte_ptr.add(OFFSET_TIMEOUT_PREOP_TO_SAFEOP + 1),
                *byte_ptr.add(OFFSET_TIMEOUT_PREOP_TO_SAFEOP + 2),
                *byte_ptr.add(OFFSET_TIMEOUT_PREOP_TO_SAFEOP + 3),
            ])
        }
    }

    /// 设置 PREOP->SAFEOP 状态转换超时 (毫秒)
    pub fn set_timeout_preop_to_safeop(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = value.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_TIMEOUT_PREOP_TO_SAFEOP + i) = bytes[i];
            }
        }
    }

    /// SAFEOP->OP 状态转换超时 (毫秒, ETG.1020 默认 5000)
    pub fn timeout_safeop_to_op(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 5000; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_TIMEOUT_SAFEOP_TO_OP),
                *byte_ptr.add(OFFSET_TIMEOUT_SAFEOP_TO_OP + 1),
                *byte_ptr.add(OFFSET_TIMEOUT_SAFEOP_TO_OP + 2),
                *byte_ptr.add(OFFSET_TIMEOUT_SAFEOP_TO_OP + 3),
            ])
        }
    }

    /// 设置 SAFEOP->OP 状态转换超时 (毫秒)
    pub fn set_timeout_safeop_to_op(&self, value: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = value.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_TIMEOUT_SAFEOP_TO_OP + i) = bytes[i];
            }
        }
    }

    // ===================== 扫描修订号匹配模式 =====================

    /// 扫描时从站版本匹配策略
    /// 0 = Exact (VendorID + ProductID + RevisionID 精确匹配)
    /// 1 = CompatibleHigher (VendorID + ProductID 匹配, RevisionID >= 配置值)
    /// 2 = IgnoreRevision (仅匹配 VendorID + ProductID, 默认)
    pub fn scan_revision_match(&self) -> u8 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 0; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_SCAN_REVISION_MATCH)
        }
    }

    /// 设置扫描修订号匹配模式 (0=Exact, 1=CompatibleHigher, 2=IgnoreRevision)
    pub fn set_scan_revision_match(&self, mode: u8) {
        if mode > 2 { return; }
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_SCAN_REVISION_MATCH) = mode;
        }
    }

    // ===================== DC 漂移补偿 =====================

    /// DC 漂移补偿开关 (默认关闭)
    /// 启用后主站周期性检测 DC 系统时间偏差并写入补偿值 (0x0920)
    pub fn drift_compensation(&self) -> bool {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return false; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            *byte_ptr.add(OFFSET_DRIFT_COMPENSATION) != 0
        }
    }

    /// 设置 DC 漂移补偿开关
    pub fn set_drift_compensation(&self, value: bool) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            *byte_ptr.add(OFFSET_DRIFT_COMPENSATION) = if value { 1 } else { 0 };
        }
    }

    // ===================== 邮箱配置 =====================

    /// 获取邮箱通信超时 (毫秒)
    ///
    /// 默认值 5000ms, 用于 CoE/FoE/SoE/EoE/VoE 等邮箱协议的通信超时。
    /// 存储在 主站共享内存中, 实时读写。
    pub fn mailbox_timeout(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 5000; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_MAILBOX_TIMEOUT),
                *byte_ptr.add(OFFSET_MAILBOX_TIMEOUT + 1),
                *byte_ptr.add(OFFSET_MAILBOX_TIMEOUT + 2),
                *byte_ptr.add(OFFSET_MAILBOX_TIMEOUT + 3),
            ])
        }
    }

    /// 设置邮箱通信超时 (毫秒)
    ///
    /// 影响 CoE/FoE/SoE/EoE/VoE 等所有邮箱协议的超时。
    /// 建议范围: 1000-30000ms, 默认 5000ms。
    pub fn set_mailbox_timeout(&self, ms: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = ms.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_MAILBOX_TIMEOUT + i) = bytes[i];
            }
        }
    }

    /// 获取邮箱通信重试次数
    ///
    /// 默认值 3, 邮箱通信失败时的自动重试次数。
    pub fn mailbox_retries(&self) -> u32 {
        let ptr = unsafe { ffi::GetMasterStateCache(self.master.index()) };
        if ptr.is_null() { return 3; }
        unsafe {
            let byte_ptr = ptr as *const u8;
            u32::from_le_bytes([
                *byte_ptr.add(OFFSET_MAILBOX_RETRIES),
                *byte_ptr.add(OFFSET_MAILBOX_RETRIES + 1),
                *byte_ptr.add(OFFSET_MAILBOX_RETRIES + 2),
                *byte_ptr.add(OFFSET_MAILBOX_RETRIES + 3),
            ])
        }
    }

    /// 设置邮箱通信重试次数
    ///
    /// 0 = 不重试, 建议 1-5 次。
    pub fn set_mailbox_retries(&self, count: u32) {
        let ptr = unsafe { ffi::GetMasterState(self.master.index()) };
        if ptr.is_null() { return; }
        unsafe {
            let byte_ptr = ptr as *mut u8;
            let bytes = count.to_le_bytes();
            for i in 0..4 {
                *byte_ptr.add(OFFSET_MAILBOX_RETRIES + i) = bytes[i];
            }
        }
    }

    // ===================== 配置导出与加载 =====================

    /// 将当前主站配置保存为 XML 文件
    ///
    /// 对应 C# XmlHelper.SaveMasterSettings()
    /// 保存内容包括: 周期时间, DC 周期时间, 预期从站数量。
    /// 返回 true 表示保存成功。
    pub fn save_config_xml(&self, path: &str) -> bool {
        let loop_cycle_us = self.loop_cycle() / 1000; // 纳秒转微秒
        let xml = format!(
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
             <DarraEtherCATConfiguration version=\"1.0\">\n\
             \x20 <Master>\n\
             \x20   <CycleTime unit=\"us\">{}</CycleTime>\n\
             \x20   <DcCycleTime unit=\"us\">{}</DcCycleTime>\n\
             \x20   <FrameHighPriority>{}</FrameHighPriority>\n\
             \x20   <UseUdp>{}</UseUdp>\n\
             \x20   <VlanId>{}</VlanId>\n\
             \x20   <VlanPriority>{}</VlanPriority>\n\
             \x20   <OverlappingGroups>{}</OverlappingGroups>\n\
             \x20   <PackedMode>{}</PackedMode>\n\
             \x20   <MutexProtection>{}</MutexProtection>\n\
             \x20   <FilterThreshold>{}</FilterThreshold>\n\
             \x20   <FrameRepeatCount>{}</FrameRepeatCount>\n\
             \x20   <ProcessDataWatchdogMs>{}</ProcessDataWatchdogMs>\n\
             \x20   <PdiWatchdogMs>{}</PdiWatchdogMs>\n\
             \x20   <AdaptiveTimeout>{}</AdaptiveTimeout>\n\
             \x20   <DriftCompensation>{}</DriftCompensation>\n\
             \x20   <ScanRevisionMatch>{}</ScanRevisionMatch>\n\
             \x20   <MailboxTimeout>{}</MailboxTimeout>\n\
             \x20   <MailboxRetries>{}</MailboxRetries>\n\
             \x20 </Master>\n\
             </DarraEtherCATConfiguration>",
            loop_cycle_us,
            loop_cycle_us, // DC 周期默认与 PDO 周期一致
            self.frame_high_priority(),
            self.use_udp(),
            self.vlan_id(),
            self.vlan_priority(),
            self.overlapping_groups(),
            self.packed_mode(),
            self.mutex_protection(),
            self.filter_threshold(),
            self.frame_repeat_count(),
            self.process_data_watchdog_ms(),
            self.pdi_watchdog_ms(),
            self.adaptive_timeout_enabled(),
            self.drift_compensation(),
            self.scan_revision_match(),
            self.mailbox_timeout(),
            self.mailbox_retries(),
        );

        std::fs::write(path, xml.as_bytes()).is_ok()
    }

    /// 将当前主站配置导出为 JSON 字符串
    ///
    /// 返回包含所有配置项的 JSON 字符串, 失败时返回 None。
    pub fn export_config_string(&self) -> Option<String> {
        // 手动构建 JSON, 不依赖外部 serde 库
        let json = format!(
            "{{\n\
             \x20 \"loop_cycle_ns\": {},\n\
             \x20 \"frame_high_priority\": {},\n\
             \x20 \"use_udp\": {},\n\
             \x20 \"udp_available\": {},\n\
             \x20 \"vlan_id\": {},\n\
             \x20 \"vlan_priority\": {},\n\
             \x20 \"overlapping_groups\": {},\n\
             \x20 \"packed_mode\": {},\n\
             \x20 \"mutex_protection\": {},\n\
             \x20 \"filter_threshold\": {},\n\
             \x20 \"frame_repeat_count\": {},\n\
             \x20 \"process_data_watchdog_ms\": {},\n\
             \x20 \"pdi_watchdog_ms\": {},\n\
             \x20 \"adaptive_timeout_enabled\": {},\n\
             \x20 \"timeout_init_to_preop\": {},\n\
             \x20 \"timeout_preop_to_safeop\": {},\n\
             \x20 \"timeout_safeop_to_op\": {},\n\
             \x20 \"drift_compensation\": {},\n\
             \x20 \"scan_revision_match\": {},\n\
             \x20 \"mailbox_timeout\": {},\n\
             \x20 \"mailbox_retries\": {}\n\
             }}",
            self.loop_cycle(),
            self.frame_high_priority(),
            self.use_udp(),
            self.is_udp_available(),
            self.vlan_id(),
            self.vlan_priority(),
            self.overlapping_groups(),
            self.packed_mode(),
            self.mutex_protection(),
            self.filter_threshold(),
            self.frame_repeat_count(),
            self.process_data_watchdog_ms(),
            self.pdi_watchdog_ms(),
            self.adaptive_timeout_enabled(),
            self.timeout_init_to_preop(),
            self.timeout_preop_to_safeop(),
            self.timeout_safeop_to_op(),
            self.drift_compensation(),
            self.scan_revision_match(),
            self.mailbox_timeout(),
            self.mailbox_retries(),
        );

        Some(json)
    }
}

// ===================== 主站状态结构偏移量 =====================
// 这些偏移量需要与 C 层 主站状态结构布局保持同步
// 可通过 DumpSlaveStructOffsets() 验证

/// frame_high_priority 字段偏移
const OFFSET_FRAME_HIGH_PRIORITY: usize = 0x100;
/// vlan_id 字段偏移
const OFFSET_VLAN_ID: usize = 0x102;
/// vlan_priority 字段偏移
const OFFSET_VLAN_PRIORITY: usize = 0x104;
/// overlapping_groups 字段偏移
const OFFSET_OVERLAPPING_GROUPS: usize = 0x105;
/// packed_mode 字段偏移
const OFFSET_PACKED_MODE: usize = 0x106;
/// filter_threshold 字段偏移
const OFFSET_FILTER_THRESHOLD: usize = 0x108;
/// frame_repeat_count 字段偏移
const OFFSET_FRAME_REPEAT_COUNT: usize = 0x10C;
/// wd_pd_timeout_ms 字段偏移
const OFFSET_WD_PD_TIMEOUT_MS: usize = 0x110;
/// wd_pdi_timeout_ms 字段偏移
const OFFSET_WD_PDI_TIMEOUT_MS: usize = 0x112;
/// adaptive_timeout_enabled 字段偏移
const OFFSET_ADAPTIVE_TIMEOUT_ENABLED: usize = 0x114;
/// timeout_init_to_preop 字段偏移
const OFFSET_TIMEOUT_INIT_TO_PREOP: usize = 0x118;
/// timeout_preop_to_safeop 字段偏移
const OFFSET_TIMEOUT_PREOP_TO_SAFEOP: usize = 0x11C;
/// timeout_safeop_to_op 字段偏移
const OFFSET_TIMEOUT_SAFEOP_TO_OP: usize = 0x120;
/// drift_compensation 字段偏移
const OFFSET_DRIFT_COMPENSATION: usize = 0x124;
/// scan_revision_match 字段偏移
const OFFSET_SCAN_REVISION_MATCH: usize = 0x125;
/// mailbox_timeout 字段偏移 (u32, 毫秒)
const OFFSET_MAILBOX_TIMEOUT: usize = 0x128;
/// mailbox_retries 字段偏移 (u32, 重试次数)
const OFFSET_MAILBOX_RETRIES: usize = 0x12C;

// ===================== 独立配置保存/加载函数 =====================

/// 保存主站基本设置到 XML 文件
///
/// 对应 C# XmlHelper.SaveMasterSettings(path, loopCycle, dcCycleUs, expectedSlaveCount)
/// loop_cycle_us: PDO 周期 (微秒)
/// dc_cycle_us: DC 周期 (微秒)
/// expected_slave_count: 预期从站数量
pub fn save_master_settings(path: &str, loop_cycle_us: u16, dc_cycle_us: u16, expected_slave_count: i32) -> bool {
    let xml = format!(
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
         <DarraEtherCATConfiguration version=\"1.0\">\n\
         \x20 <Master>\n\
         \x20   <CycleTime unit=\"us\">{}</CycleTime>\n\
         \x20   <DcCycleTime unit=\"us\">{}</DcCycleTime>\n\
         \x20   <ExpectedSlaveCount>{}</ExpectedSlaveCount>\n\
         \x20 </Master>\n\
         </DarraEtherCATConfiguration>",
        loop_cycle_us, dc_cycle_us, expected_slave_count
    );

    std::fs::write(path, xml.as_bytes()).is_ok()
}

/// 从 XML 文件加载主站基本设置
///
/// 对应 C# XmlHelper.LoadMasterSettings(path)
/// 返回 true 表示加载成功, 加载的值通过 out 参数返回。
/// 失败时返回 false, 并使用默认值 (1000us, 1000us)。
pub fn load_master_settings(path: &str) -> (bool, u16, u16) {
    // 默认值
    let mut loop_cycle: u16 = 1000;
    let mut dc_cycle: u16 = 1000;

    let content = match std::fs::read_to_string(path) {
        Ok(c) => c,
        Err(_) => return (false, loop_cycle, dc_cycle),
    };

    // 检查根节点
    if !content.contains("DarraEtherCATConfiguration") {
        return (false, loop_cycle, dc_cycle);
    }

    // 简易 XML 解析 (提取 CycleTime 和 DcCycleTime 的值)
    if let Some(val) = extract_xml_value(&content, "CycleTime") {
        if let Ok(v) = val.parse::<u16>() {
            if v > 0 { loop_cycle = v; }
        }
    }
    if let Some(val) = extract_xml_value(&content, "DcCycleTime") {
        if let Ok(v) = val.parse::<u16>() {
            if v > 0 { dc_cycle = v; }
        }
    }

    (true, loop_cycle, dc_cycle)
}

/// 简易 XML 值提取 (不依赖外部 XML 库)
fn extract_xml_value(xml: &str, tag: &str) -> Option<String> {
    let open_tag = format!("<{}", tag);
    let close_tag = format!("</{}>", tag);

    let start_pos = xml.find(&open_tag)?;
    let after_open = &xml[start_pos..];
    // 跳过开标签的属性和 '>'
    let content_start = after_open.find('>')? + 1;
    let remaining = &after_open[content_start..];
    let end_pos = remaining.find(&close_tag)?;
    let value = remaining[..end_pos].trim();
    if value.is_empty() { None } else { Some(value.to_string()) }
}

impl<'a> std::fmt::Display for MasterConfig<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let cycle_us = self.loop_cycle() as f64 / 1000.0;
        write!(f, "MasterConfig(cycle={:.0}us, mutex={}, mbx_timeout={}ms, mbx_retries={})",
               cycle_us,
               if self.mutex_protection() { "on" } else { "off" },
               self.mailbox_timeout(),
               self.mailbox_retries())
    }
}
