//! 数据结构定义
//!
//! 对应 C# Master/Data/Structures.cs
//! 包含 EtherCAT 协议常量、PDO 统计、从站结构体等。

/// 增强型 EtherCAT 常量
pub mod constants {
    /// 邮箱协议: AoE
    pub const ECT_MBXPROT_AOE: u16 = 0x0001;
    /// 邮箱协议: EoE
    pub const ECT_MBXPROT_EOE: u16 = 0x0002;
    /// 邮箱协议: CoE
    pub const ECT_MBXPROT_COE: u16 = 0x0004;
    /// 邮箱协议: FoE
    pub const ECT_MBXPROT_FOE: u16 = 0x0008;
    /// 邮箱协议: SoE
    pub const ECT_MBXPROT_SOE: u16 = 0x0010;
    /// 邮箱协议: VoE
    pub const ECT_MBXPROT_VOE: u16 = 0x0020;

    /// CoE 详细: SDO
    pub const ECT_COEDET_SDO: u8 = 0x01;
    /// CoE 详细: SDO 信息
    pub const ECT_COEDET_SDOINFO: u8 = 0x02;
    /// CoE 详细: PDO 分配
    pub const ECT_COEDET_PDOASSIGN: u8 = 0x04;
    /// CoE 详细: PDO 配置
    pub const ECT_COEDET_PDOCONFIG: u8 = 0x08;
    /// CoE 详细: 上传
    pub const ECT_COEDET_UPLOAD: u8 = 0x10;
    /// CoE 详细: SDO CA
    pub const ECT_COEDET_SDOCA: u8 = 0x20;
}

/// PDO 性能统计
///
/// 对应 C# Structures.PDOStats [Pack=1]: uint*5 + ulong*4
#[derive(Clone, Debug, Default)]
#[repr(C, packed)]
pub struct PdoStats {
    pub read_count: u32,
    pub write_count: u32,
    pub error_count: u32,
    pub total_bytes_read: u32,
    pub total_bytes_written: u32,
    pub last_cycle_time_ns: u64,
    pub min_cycle_time_ns: u64,
    pub max_cycle_time_ns: u64,
    pub avg_cycle_time_ns: u64,
}

/// PDO 映射项
///
/// 对应 C# PDOMappingEntry
#[derive(Clone, Debug)]
#[repr(C, packed)]
pub struct PdoMappingEntry {
    pub index: u16,
    pub sub_index: u8,
    pub bit_length: u8,
    pub bit_offset: u16,
    pub name: [u8; 64],
    pub unit: [u8; 16],
    pub readable: u8,
    pub writable: u8,
}

/// 通信统计信息
///
/// 对应 C# ec_communication_stats
#[derive(Clone, Debug, Default)]
#[repr(C, packed)]
pub struct CommunicationStatsLocal {
    pub total_cycles: u32,
    pub successful_cycles: u32,
    pub failed_cycles: u32,
    pub timeout_cycles: u32,
    pub average_cycle_time_us: f64,
    pub max_cycle_time_us: f64,
    pub min_cycle_time_us: f64,
}

/// 从站详细信息
///
/// 对应 C# ec_slave_info
#[derive(Clone, Debug, Default)]
pub struct SlaveInfo {
    pub vendor_id: u32,
    pub product_code: u32,
    pub revision_number: u32,
    pub serial_number: u32,
    pub device_name: String,
    pub vendor_name: String,
    pub sync_manager_count: u16,
    pub fmmu_count: u16,
    pub supports_coe: bool,
    pub supports_foe: bool,
    pub supports_eoe: bool,
    pub supports_soe: bool,
}

/// 实时统计信息
///
/// 对应 C# ec_realtime_stats
#[derive(Clone, Debug, Default)]
#[repr(C, packed)]
pub struct RealtimeStats {
    pub current_cycle_time_us: f64,
    pub jitter_us: f64,
    pub lost_frames: u32,
    pub corrupted_frames: u32,
    pub bus_utilization: f64,
}

// ===================== 网络适配器信息结构体 =====================

/// 网络适配器信息 - 对应 C# ec_networkinfo_t
///
/// 必须与 Core.h 中的定义完全一致（Pack=1, 总大小260字节）
#[derive(Clone, Debug)]
#[repr(C, packed)]
pub struct NetworkInfo {
    /// 适配器名称
    pub name: [u8; 128],
    /// 适配器描述
    pub desc: [u8; 128],
    /// 从站数量
    pub slave_num: i16,
    /// 受冗余保护的从站数
    pub redundant_slave_num: i16,
}

// ===================== SyncManager 配置结构体 =====================

/// SyncManager 配置 - 对应 C# ec_smt
#[derive(Clone, Copy, Debug, Default)]
#[repr(C, packed)]
pub struct EcSmt {
    /// SM 起始地址
    pub start_addr: u16,
    /// SM 长度
    pub sm_length: u16,
    /// SM 标志
    pub sm_flags: u32,
}

// ===================== FMMU 配置结构体 =====================

/// FMMU 配置 - 对应 C# ec_fmmut
#[derive(Clone, Copy, Debug, Default)]
#[repr(C, packed)]
pub struct EcFmmut {
    /// 逻辑起始地址
    pub log_start: u32,
    /// 逻辑长度
    pub log_length: u16,
    /// 逻辑起始位
    pub log_start_bit: u8,
    /// 逻辑结束位
    pub log_end_bit: u8,
    /// 物理起始地址
    pub phys_start: u16,
    /// 物理起始位
    pub phys_start_bit: u8,
    /// FMMU 类型
    pub fmmu_type: u8,
    /// FMMU 激活
    pub fmmu_active: u8,
    /// 保留
    pub unused1: u8,
    /// 保留
    pub unused2: u16,
}

// ===================== Slave I/O 描述符 (slave_io_desc_t) =====================

/// Slave I/O 描述符 - 对应 C 端 master.h 中 `slave_io_desc_t`
///
/// 原平面字段 obits/obytes/outputs/ooffset/ostartbit (×2 输入/输出) 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (dtype 之后, sm 之前) 各 1 个 (output / input).
/// 自然对齐 (`#[repr(C)]`), 64 位下 24 字节: bits(2)+pad(2)+bytes(4)+ptr(8)+offset(4)+startbit(1)+pad(3).
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveIoDesc {
    /// I/O 位数
    pub bits: u16,
    /// I/O 字节数
    pub bytes: u32,
    /// I/O 指针 (IOmap 中, uint8_t*)
    pub ptr: usize,
    /// I/O 偏移 (IOmap 中)
    pub offset: u32,
    /// 第一个 I/O 字节的起始位
    pub startbit: u8,
}

// ===================== Slave FSoE 子结构 (ETG.5100/5120) =====================

/// Slave FSoE 子结构 - 对应 C 端 master.h 中 `slave_fsoe_t`
///
/// Phase 2-E: 嵌入到 EcSlave 中段 (alias_addr 之后, output 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: capable (1) + 7 字节隐式填充 + connection (8) + sm_context (8) +
///          connection_id/safety_address/safe_input_size/safe_output_size (8) +
///          pdo_input_offset/pdo_output_offset (8) = 40 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveFsoe {
    /// FSoE 能力标志
    pub capable: u8,
    /// FSoE 连接指针
    pub connection: usize,
    /// FSoE 状态机上下文指针
    pub sm_context: usize,
    /// FSoE 连接 ID
    pub connection_id: u16,
    /// FSoE 安全地址
    pub safety_address: u16,
    /// FSoE 安全输入大小（字节）
    pub safe_input_size: u16,
    /// FSoE 安全输出大小（字节）
    pub safe_output_size: u16,
    /// FSoE PDO 输入偏移
    pub pdo_input_offset: u32,
    /// FSoE PDO 输出偏移
    pub pdo_output_offset: u32,
}

// ===================== Slave 邮箱子结构 (与 master.h slave_mailbox_t 一致) =====================

/// Slave 邮箱子结构 - 对应 C 端 master.h 中 `slave_mailbox_t`
///
/// 原平面字段 mbx_l / mbx_wo / mbx_rl / mbx_ro / mbx_proto / mbx_cnt 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (FMMU 函数之后, hasdc 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: 5 × u16 (10) + u8 (1) + 1 字节隐式填充 = 12 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveMailbox {
    /// 写邮箱长度 (mbx_l)
    pub length: u16,
    /// 写邮箱偏移 (mbx_wo)
    pub write_offset: u16,
    /// 读邮箱长度 (mbx_rl)
    pub read_length: u16,
    /// 读邮箱偏移 (mbx_ro)
    pub read_offset: u16,
    /// 支持的邮箱协议 ECT_MBXPROT_* (mbx_proto)
    pub supported_proto: u16,
    /// 邮箱链路层协议计数器 (mbx_cnt)
    pub cnt: u8,
}

// ===================== Slave EEPROM 配置子结构 (与 master.h slave_eeprom_config_t 一致) =====================

/// Slave EEPROM 配置子结构 - 对应 C 端 master.h 中 `slave_eeprom_config_t`
///
/// 原平面字段 SIIindex / eep_8byte / eep_pdi 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (dc_active 之后, coe_details 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: u16 (2) + u8 (1) + u8 (1) = 4 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveEepromConfig {
    /// SII 配置索引 (SIIindex)
    pub sii_index: u16,
    /// 1=8字节读, 0=4字节读 (eep_8byte)
    pub read_8byte: u8,
    /// 0=EEPROM归主站, 1=归PDI (eep_pdi)
    pub pdi: u8,
}

// ===================== Slave 邮箱处理器子结构 (与 master.h slave_handler_t 一致) =====================

/// Slave 邮箱处理器子结构 - 对应 C 端 master.h 中 `slave_handler_t`
///
/// 原平面字段 mbxhandlerstate / mbxrmpstate / mbxinstateex 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (po2so_config 之后, coe_mbx_in 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: i32 (4) + i32 (4) + u16 (2) + 2 字节隐式填充 = 12 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveHandler {
    /// 邮箱处理状态 (mbxhandlerstate, 0=no handler, 1=cyclic, 2=lost)
    pub state: i32,
    /// 邮箱 RMP 状态 (mbxrmpstate)
    pub rmp_state: i32,
    /// 邮箱扩展状态 (mbxinstateex)
    pub instate_ex: u16,
}

// ===================== Slave Identity 子结构 (Phase 2-E, 与 master.h slave_identity_t 一致) =====================

/// Slave Identity 子结构 - 对应 C 端 `slave_identity_t`
///
/// Phase 2-E: 把原平面 eep_man / eep_id / eep_rev / eep_ser / itype / dtype 收敛进 metadata.identity.
/// 自然对齐 (`#[repr(C)]`), 4×u32 + 2×u16 = 20 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveIdentity {
    /// 厂商 ID (EEPROM, 原 eep_man)
    pub vendor_id: u32,
    /// 产品 ID (EEPROM, 原 eep_id)
    pub product_id: u32,
    /// 修订版本 (EEPROM, 原 eep_rev)
    pub revision: u32,
    /// 序列号 (EEPROM, 原 eep_ser)
    pub serial: u32,
    /// 接口类型 (原 Itype)
    pub itype: u16,
    /// 设备类型 (原 Dtype)
    pub dtype: u16,
}

// ===================== Slave Metadata 子结构 (与 master.h slave_metadata_t 一致) =====================

/// Slave Metadata 子结构 - 对应 C 端 master.h 中 `slave_metadata_t`
///
/// Phase 2-E: 头部新增 identity 子结构 (vendor/product/revision/serial/itype/dtype).
/// 嵌入到 EcSlave 中段 (mbx_status 之后), 自然对齐 (`#[repr(C)]`).
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct SlaveMetadata {
    /// 厂商/产品/修订/序列/接口类型/设备类型 (Phase 2-E)
    pub identity: SlaveIdentity,
    /// 组名称 (EC_MAXNAME + 1)
    pub group_name: [u8; 41],
    /// 设备名称 (EC_MAXNAME + 1)
    pub device_name: [u8; 41],
    /// SM 数量 (sync_manager_count)
    pub sm_count: u16,
}

impl Default for SlaveMetadata {
    fn default() -> Self {
        Self {
            identity: SlaveIdentity::default(),
            group_name: [0; 41],
            device_name: [0; 41],
            sm_count: 0,
        }
    }
}

// ===================== Slave Capabilities 子结构 (与 master.h slave_capabilities_t 一致) =====================

/// Slave Capabilities 子结构 - 对应 C 端 master.h 中 `slave_capabilities_t`
///
/// Darra 扩展字段 is_optional / supports_frame_repeat / mailbox_side 收敛为 sub-struct.
/// Phase 2-E: 追加 coe/foe/eoe/soe details (原平面字段).
/// 自然对齐 (`#[repr(C)]`), 7 字节 + 1 字节填充.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveCapabilities {
    /// 0=必须从站, 1=可选 (缺席不影响 WKC)
    pub is_optional: u8,
    /// 0=不支持, 1=支持 ETG.1500 帧重复
    pub supports_frame_repeat: u8,
    /// 0=auto/dual, 1=primary_only, 2=secondary_only
    pub mailbox_side: u8,
    /// CoE 协议详情 (原 CoEdetails, Phase 2-E 移入)
    pub coe_details: u8,
    /// FoE 协议详情 (原 FoEdetails, Phase 2-E 移入)
    pub foe_details: u8,
    /// EoE 协议详情 (原 EoEdetails, Phase 2-E 移入)
    pub eoe_details: u8,
    /// SoE 协议详情 (原 SoEdetails, Phase 2-E 移入)
    pub soe_details: u8,
}

// ===================== Slave Runtime 子结构 (Phase 2-E, 与 master.h slave_runtime_t 一致) =====================

/// Slave Runtime 子结构 - 对应 C 端 `slave_runtime_t`
///
/// Phase 2-E: 把原平面 ebus_current / block_lrw / group / islost 收敛.
/// 自然对齐 (`#[repr(C)]`), 6 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveRuntime {
    /// E-bus 电流 (mA)
    pub ebus_current: i16,
    /// 若 >0 禁止使用 LRW
    pub block_lrw: u8,
    /// 分组
    pub group: u8,
    /// 从站是否丢失 (FFI bool 不稳, 用 u8)
    pub is_lost: u8,
}

// ===================== Slave SM/FMMU 配置 sub-struct (Phase 2-E, 与 master.h slave_sm_fmmu_t 一致) =====================

/// Slave SM/FMMU 配置 sub-struct - 对应 C 端 `slave_sm_fmmu_t`
///
/// Phase 2-E: 收敛 SMtype[8] / SM_app_length[8] / FMMU{0..3}func / FMMUunused.
/// 自然对齐 (`#[repr(C)]`), 8 + 16 + 4 + 1 + 3 字节填充 = 32 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveSmFmmu {
    /// SM 类型 (原平面 SMtype[MAXSM])
    pub sm_type: [u8; 8],
    /// SM 应用长度 (原 SM_app_length)
    pub sm_app_length: [u16; 8],
    /// FMMU 0..3 功能类型 (原 FMMU{0..3}func)
    pub fmmu_func: [u8; 4],
    /// 第一个未使用的 FMMU 索引 (原 FMMUunused)
    pub fmmu_unused: u8,
}

// ===================== Slave 协议邮箱 sub-struct (Phase 2-E, 与 master.h slave_proto_mbx_t 一致) =====================

/// Slave 协议邮箱 sub-struct - 对应 C 端 `slave_proto_mbx_t`
///
/// Phase 2-E: 6 个协议 (CoE/SoE/FoE/EoE/VoE/AoE) 共用此 sub-struct,
/// 替换原平面 *embxin / *embxinfull / *embxoverrun.
/// 自然对齐 (`#[repr(C)]`), 64 位下: ptr (8) + u8 (1) + 3 字节填充 + i32 (4) = 16 字节.
/// `in` 是 Rust 关键字, 字段命名为 `in_ptr`.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveProtoMbx {
    /// 邮箱输入缓冲区指针 (原 *embxin)
    pub in_ptr: usize,
    /// 邮箱输入标志 (原 *embxinfull)
    pub in_full: u8,
    /// 邮箱溢出计数 (原 *embxoverrun)
    pub overrun: i32,
}

// ===================== Slave PDO 配置子结构 (与 master.h slave_pdo_config_t 一致) =====================

/// Slave PDO 配置子结构 - 对应 C 端 master.h 中 `slave_pdo_config_t`
///
/// 原平面字段 pdo_assignment_enabled / pdo_configuration_enabled / pdo_config_initialized /
/// supports_complete_access 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (mbx_status 之后, 跟 metadata 相邻), 自然对齐 (`#[repr(C)]`), 4 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlavePdoConfig {
    /// 是否写入 PDO Assignment 0x1C12/0x1C13 (pdo_assignment_enabled)
    pub assignment_enabled: u8,
    /// 是否写入 PDO Configuration (pdo_configuration_enabled)
    pub configuration_enabled: u8,
    /// PDO 配置是否已从 ESI 初始化 (pdo_config_initialized)
    pub config_initialized: u8,
    /// 是否支持 Complete Access (supports_complete_access)
    pub supports_complete_access: u8,
}

// ===================== Slave 拓扑子结构 (与 master.h slave_topology_t 一致) =====================

/// Slave 拓扑子结构 - 对应 C 端 master.h 中 `slave_topology_t`
///
/// 原平面字段 hasdc / ptype / topology / activeports / consumedports / parent / parentport /
/// entryport 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (mbx 之后, eeprom_config 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: 5×u8 (5) + 1 字节填充 + u16 (2) + 2×u8 (2) = 10 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveTopology {
    /// 是否支持 DC (hasdc)
    pub has_dc: u8,
    /// 物理端口类型 (ptype)
    pub phy_type: u8,
    /// 拓扑类型 (topology)
    pub link_count: u8,
    /// 活动端口位图 (activeports)
    pub active_ports: u8,
    /// 已使用端口位图 (consumedports)
    pub consumed_ports: u8,
    /// 父从站站地址 (parent)
    pub parent: u16,
    /// 父从站端口号 (parentport)
    pub parent_port: u8,
    /// 入口端口号 (entryport)
    pub entry_port: u8,
}

// ===================== Slave DC 子结构 (与 master.h slave_dc_t 一致) =====================

/// Slave DC 子结构 - 对应 C 端 master.h 中 `slave_dc_t`
///
/// 原平面字段 DCrtA..D / pdelay / DCnext / DCprevious / DCcycle / DCcycle1 / DCshift /
/// DCactive 收敛为 sub-struct.
/// 嵌入到 EcSlave 中段 (topo 之后, eeprom_config 之前), 自然对齐 (`#[repr(C)]`).
/// 64 位下: i32[4] (16) + i32 (4) + 2×u16 (4) + 3×i32 (12) + u16 (2) + 2 字节尾部填充 = 40 字节.
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct SlaveDc {
    /// 端口 A/B/C/D DC 接收时间 (纳秒) (DCrtA..D)
    pub recvtime: [i32; 4],
    /// 传播延迟 (纳秒) (pdelay)
    pub propagation_delay: i32,
    /// DC 链中下一个从站 (DCnext)
    pub next: u16,
    /// DC 链中上一个从站 (DCprevious)
    pub prev: u16,
    /// DC SYNC0 周期 (纳秒) (DCcycle)
    pub cycle0: i32,
    /// DC SYNC1 周期 (纳秒) (DCcycle1)
    pub cycle1: i32,
    /// DC 相位偏移 (纳秒) (DCshift)
    pub shift: i32,
    /// DC AssignActivate 值, 0=禁用 (DCactive)
    pub active: u16,
}

// ===================== 从站结构体 =====================

/// 从站结构体 - 对应 C# 从站结构 (字节级一致)
///
/// 必须与 ec_main.h 中的 C 结构完全一致（64位自然对齐, Phase 2-E 重排）.
///
/// Phase 2-E 字段顺序基准:
/// state, ALstatuscode, configadr, aliasadr,
/// fsoe, output, input,
/// SM[8], FMMU[4],
/// sm_fmmu (sm_type[8]/sm_app_length[8]/fmmu_func[4]/fmmu_unused),
/// mbx, topo, dc, eeprom_config,
/// runtime (ebus_current/block_lrw/group/is_lost),
/// PO2SOconfig, handler,
/// coe, soe, foe, eoe, voe, aoe (slave_proto_mbx_t),
/// mbxstatus,
/// metadata (identity{vendor_id/product_id/revision/serial/itype/dtype} + names + sm_count),
/// pdo_config,
/// capabilities (is_optional/supports_frame_repeat/mailbox_side/coe/foe/eoe/soe details).
#[derive(Clone, Debug)]
#[repr(C)]
pub struct EcSlave {
    // ==================== 基本状态字段 ====================
    /// 当前 EtherCAT 状态
    pub state: u16,
    /// AL 状态码
    pub al_status_code: u16,
    /// 配置地址
    pub config_addr: u16,
    /// 别名地址
    pub alias_addr: u16,

    // ==================== FSoE 子结构 (Phase 1) ====================
    /// FSoE 安全协议子结构 (slave_fsoe_t)
    pub fsoe: SlaveFsoe,

    // ==================== I/O 描述符 sub-struct ====================
    /// 输出 (PDO Tx from master), 24 字节
    pub output: SlaveIoDesc,
    /// 输入 (PDO Rx to master), 24 字节
    pub input: SlaveIoDesc,

    // ==================== SM/FMMU 数组 ====================
    /// 8 个 SyncManager 条目
    pub sm: [EcSmt; 8],
    /// 4 个 FMMU 条目
    pub fmmu: [EcFmmut; 4],

    // ==================== SM/FMMU 配置 sub-struct (Phase 2-E) ====================
    /// 替换原平面 SMtype[8] / SM_app_length[8] / FMMU{0..3}func / FMMUunused.
    pub sm_fmmu: SlaveSmFmmu,

    // ==================== 邮箱配置 sub-struct ====================
    /// 邮箱长度/偏移/协议/计数器
    pub mbx: SlaveMailbox,

    // ==================== 拓扑 sub-struct ====================
    /// 拓扑信息 (slave_topology_t)
    pub topo: SlaveTopology,

    // ==================== DC sub-struct ====================
    /// DC 信息 (slave_dc_t)
    pub dc: SlaveDc,

    // ==================== EEPROM 配置 sub-struct ====================
    /// SII 配置索引 + EEPROM 读宽度 + PDI 标志
    pub eeprom_config: SlaveEepromConfig,

    // ==================== Runtime sub-struct (Phase 2-E) ====================
    /// 替换原平面 ebus_current / block_lrw / group / islost.
    pub runtime: SlaveRuntime,

    // ==================== 函数指针 ====================
    /// PO->SO 配置函数指针
    pub po2so_config: usize,

    // ==================== 邮箱处理器 sub-struct ====================
    /// 邮箱处理器状态
    pub handler: SlaveHandler,

    // ==================== 6 协议邮箱 (Phase 2-E 收敛为 SlaveProtoMbx) ====================
    /// CoE 邮箱状态
    pub coe: SlaveProtoMbx,
    /// SoE 邮箱状态
    pub soe: SlaveProtoMbx,
    /// FoE 邮箱状态
    pub foe: SlaveProtoMbx,
    /// EoE 邮箱状态
    pub eoe: SlaveProtoMbx,
    /// VoE 邮箱状态
    pub voe: SlaveProtoMbx,
    /// AoE 邮箱状态
    pub aoe: SlaveProtoMbx,

    // ==================== 邮箱状态 ====================
    /// 输出邮箱状态寄存器缓冲区指针
    pub mbx_status: usize,

    // ==================== Metadata 子结构 (Phase 2-E: 头部新增 identity) ====================
    /// 厂商/产品/修订/序列/itype/dtype + 组名/设备名/SM 数量
    pub metadata: SlaveMetadata,

    // ==================== PDO 配置子结构 ====================
    /// PDO Assignment/Config 开关 + CA 支持
    pub pdo_config: SlavePdoConfig,

    // ==================== Capabilities 子结构 (Phase 2-E: 追加 4 协议 details) ====================
    /// 可选标记 / 帧重复 / 邮箱单侧路由 / coe/foe/eoe/soe details
    pub capabilities: SlaveCapabilities,
}

// ===================== 主站状态结构体 =====================

/// 主站状态结构 - 对应 C# 主站状态结构
///
/// 所有主站配置属性都存储在此结构中
/// 通过 GetMasterState() 获取指针后直接读写字段
#[derive(Clone, Debug)]
#[repr(C)]
pub struct EcState {
    // ==================== EtherCAT 状态 ====================
    /// 当前 EtherCAT 状态
    pub state: u16,
    /// AL 状态码
    pub al_status_code: u16,
    /// 网络中的从站数量
    pub slave_count: i32,

    // ==================== 时间配置 ====================
    /// 循环周期时间（纳秒）
    pub loop_cycle: u32,
    /// DC 诊断监控基准周期（纳秒）
    pub dc_cycle: u32,
    /// DC 时间（实时值）
    pub dc_time: i64,

    // ==================== PDO 数据缓冲区 ====================
    /// IO 映射缓冲区
    pub iomap: [u8; 65536],
    /// IOmap 访问同步互斥锁
    pub iomap_mutex: usize,

    /// 双缓冲区
    pub iomap_buffer: [u8; 65536],
    /// 版本计数器
    pub buffer_version: u32,
    /// 脏标志
    pub buffer_dirty: u8,

    // ==================== 互斥锁保护配置 ====================
    /// 1 = 自动锁定, 0 = 无自动锁定
    pub mutex_protection: u8,

    // ==================== CPU 亲和性配置 ====================
    /// PDO 线程 CPU 核心绑定 (-1 = 未配置)
    pub pdo_cpu_affinity: i8,

    // ==================== DC 自动偏移配置 ====================
    /// 0 = 禁用, 1 = 启用
    pub dc_auto_shift_enabled: u8,

    // ==================== 网络配置 ====================
    /// 0 = 标准帧, 1 = UDP 帧
    pub use_udp: u8,

    // ==================== 可选功能开关 ====================
    /// 自适应超时 (0=禁用, 1=启用)
    pub adaptive_timeout_enabled: u8,

    // ==================== PDO 通信优化 ====================
    /// 重叠组 (0=禁用, 1=启用)
    pub overlapping_groups: u8,

    /// Packed PDO 映射 (0=字节对齐默认, 1=bit紧密映射)
    pub packed_mode: u8,

    // ==================== 帧优先级配置 ====================
    /// 帧高优先级 (0=禁用, 1=启用)
    pub frame_high_priority: u8,

    // ==================== VLAN 配置 ====================
    /// VLAN ID (0=禁用)
    pub vlan_id: u16,
    /// VLAN 优先级 (0-7)
    pub vlan_priority: u8,

    // ==================== 状态转换超时 (ETG.1020) ====================
    /// INIT->PREOP 超时 (ms)
    pub timeout_init_to_preop: u32,
    /// PREOP->SAFEOP 超时 (ms)
    pub timeout_preop_to_safeop: u32,
    /// SAFEOP->OP 超时 (ms)
    pub timeout_safeop_to_op: u32,

    // ==================== 看门狗配置 (ETG.1000.4) ====================
    /// 过程数据看门狗超时 (ms)
    pub wd_pd_timeout_ms: u16,
    /// PDI 看门狗超时 (ms)
    pub wd_pdi_timeout_ms: u16,

    /// 判断滤波阈值
    pub filter_threshold: u32,

    // ==================== 帧重复 (ETG.1500 5.4.3) ====================
    /// 帧重复次数
    pub frame_repeat_count: u8,

    // ==================== 组配置 ====================
    /// 活跃组数量
    pub active_group_count: u8,
    /// 对齐填充
    pub _group_pad: [u8; 2],
    /// 8组 x 8字节 = 64字节
    pub group_config_raw: [u8; 64],
}

// ===================== 内部诊断数据结构体 =====================

/// 内部诊断数据结构 - 对应 C 层 internal_diagnostics_t
///
/// 这是所有统计信息的唯一所有者
/// 使用 GetDiagnosticsPointer() 进行零拷贝访问
/// 注意：不使用 packed，因为 C 端也使用自然对齐
#[derive(Clone, Debug)]
#[repr(C)]
pub struct InternalDiagnostics {
    // ==================== 实时性能数据 ====================
    /// 当前秒内的周期计数
    pub cache_cnt: u32,
    /// 上一秒的周期计数（频率Hz）
    pub rt_cnt: u32,
    /// 累计总周期数
    pub cycle_count: u32,

    /// 当前秒内的错误计数
    pub error_cache_cnt: u32,
    /// 上一秒的错误计数
    pub error_cnt: u32,

    /// 当前工作计数器
    pub wkc: u16,
    /// 期望工作计数器
    pub expected_wkc: u16,

    /// 最近一次周期耗时（微秒）
    pub cycle_time_span: u32,

    // ==================== 帧错误统计（累计） ====================
    /// 总帧错误数
    pub frame_errors: u32,
    /// 丢失帧数
    pub lost_frames: u32,
    /// 乱序帧数
    pub out_of_order_frames: u32,
    /// 校验和错误数
    pub checksum_errors: u32,
    /// 超时帧数
    pub timeout_frames: u32,

    // ==================== 从站级错误计数器 (EC_MAXSLAVE=512) ====================
    /// 每个从站的接收错误计数
    pub rx_error_count: [u32; 512],
    /// 每个从站的发送错误计数
    pub tx_error_count: [u32; 512],
    /// 每个从站的链路丢失计数
    pub lost_link_count: [u16; 512],
    /// 每个从站的无效帧计数
    pub invalid_frame_count: [u16; 512],

    // ==================== WKC 统计 ====================
    /// WKC 错误次数
    pub working_counter_errors: u16,
    /// 连续 WKC 错误次数
    pub consecutive_wkc_errors: u16,
    /// WKC 不匹配总次数
    pub total_wkc_mismatches: u32,

    // ==================== 时间统计 ====================
    /// 周期开始时间戳（纳秒）
    pub cycle_start_time: u64,
    /// 周期时间累加器
    pub cycle_time_accumulator: f64,
    /// 上次快照时间戳（秒）
    pub last_snapshot_time: u64,
    /// 上次快照时的 cycle_count
    pub snapshot_cycle_count: u32,

    // ==================== 抖动统计 (1秒窗口) ====================
    /// 上一次周期时间（微秒）
    pub last_cycle_time_us: f64,
    /// 1秒内抖动累加器
    pub jitter_accumulator: f64,
    /// 1秒内最大抖动（微秒）
    pub max_jitter_in_second: f64,
    /// 当前秒抖动采样数 (cur_sec_jitter_count)
    pub jitter_sample_count: u32,

    // [2026-05-08 删除] 此处之前定义的 avg_jitter_us / max_jitter_us / cycle_time_sample_count /
    //   primary_port_*/secondary_port_*/link_quality_percent[512]/last_good_frame_time[512]/
    //   initialized/enabled/win_*/win_head/win_filled 全部偏移错位.
    // C 端这块内存实际是 sec_max_jitter[3]/sec_acc_jitter[3]/sec_jitter_count[3]/jitter_ring_idx/
    //   sec_bus_max_jitter[3]/avg_jitter_us/max_jitter_us/cycle_time_sample_count/bus_*/...
    //   字段顺序、类型、偏移都不同, Rust 读出的值都不对.
    // 这块全量诊断数据请走专用 API (例如 Other/diagnostics_info 路径) 获取快照,
    //   不要依赖此 struct 形状.
    // (同步 C# 修复, 保持跨语言镜像一致.)
}

// [2026-05-08 已废弃, Phase 2-x 重构后无引用] 5 个废弃 struct 同步从 C# 镜像清理:
//   - EcAdapterEnhanced       (ec_adapter_enhanced)        — 适配器列表改走独立 API
//   - EcStartupParam          (ec_startup_param_t, legacy) — 字段定义错, 正确版在 ffi 模块
//   - EcConfigListEnhanced    (ec_configlist_enhanced)     — 改走 ec_slave_blittable + GetSlave()
//   - EcStartupListEnhanced   (ec_startuplist_enhanced)    — 同上
//   - EcDcListEnhanced        (ec_dclist_enhanced)         — 同上
// 删除原因: DLL Phase 2-x 重构后这 5 个 struct 在 Rust SDK 中 0 引用, 保留会误导维护.
// (与 C#/Java/Python/CPP 镜像同步删除以保持跨语言一致.)

// ===================== FoE 扩展选项结构体 =====================

/// FoE 扩展选项
///
/// 对应 C# FoEOptions (Rust 版本)
#[derive(Clone, Debug)]
pub struct FoEOptionsLocal {
    /// 启用 CRC 校验
    pub enable_crc: bool,
    /// 严格模式
    pub strict_mode: bool,
    /// 自动在文件名后附加 CRC 标记
    pub auto_append_crc: bool,
    /// 预期的 CRC 值
    pub expected_crc: u32,
}

impl Default for FoEOptionsLocal {
    fn default() -> Self {
        Self {
            enable_crc: false,
            strict_mode: true,
            auto_append_crc: true,
            expected_crc: 0,
        }
    }
}

// ===================== 组配置辅助方法 =====================

/// 组配置辅助方法
///
/// 对应 C# EcGroupConfigHelper
/// 操作 主站状态.group_config_raw 中每组 8 字节的配置数据。
/// 布局: [enabled:1][cycle_divider:1][expected_wkc:2][slave_count:2][frame_repeat_eligible:1][reserved:1]
pub struct EcGroupConfigHelper;

impl EcGroupConfigHelper {
    const GROUP_CONFIG_SIZE: usize = 8;

    /// 获取组是否启用
    pub fn get_group_enabled(raw: &[u8], group: u8) -> bool {
        if group >= 8 { return false; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE] != 0
    }

    /// 设置组启用状态
    pub fn set_group_enabled(raw: &mut [u8], group: u8, enabled: bool) {
        if group >= 8 { return; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE] = if enabled { 1 } else { 0 };
    }

    /// 获取组周期分频器
    pub fn get_group_cycle_divider(raw: &[u8], group: u8) -> u8 {
        if group >= 8 { return 0; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE + 1]
    }

    /// 设置组周期分频器
    pub fn set_group_cycle_divider(raw: &mut [u8], group: u8, divider: u8) {
        if group >= 8 { return; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE + 1] = divider;
    }

    /// 获取组期望 WKC (小端)
    pub fn get_group_expected_wkc(raw: &[u8], group: u8) -> u16 {
        if group >= 8 { return 0; }
        let off = group as usize * Self::GROUP_CONFIG_SIZE + 2;
        u16::from_le_bytes([raw[off], raw[off + 1]])
    }

    /// 获取组从站数量 (小端)
    pub fn get_group_slave_count(raw: &[u8], group: u8) -> u16 {
        if group >= 8 { return 0; }
        let off = group as usize * Self::GROUP_CONFIG_SIZE + 4;
        u16::from_le_bytes([raw[off], raw[off + 1]])
    }

    /// 获取组帧重复资格 (ETG.1500 5.4.3)
    pub fn get_group_frame_repeat_eligible(raw: &[u8], group: u8) -> bool {
        if group >= 8 { return false; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE + 6] != 0
    }

    /// 设置组帧重复资格 (ETG.1500 5.4.3)
    pub fn set_group_frame_repeat_eligible(raw: &mut [u8], group: u8, eligible: bool) {
        if group >= 8 { return; }
        raw[group as usize * Self::GROUP_CONFIG_SIZE + 6] = if eligible { 1 } else { 0 };
    }
}
