/**
 * @file mqtt50_client_auto_test_demo.c
 * @brief MQTT5.0 商用级自动化测试用例集（完全适配SDK v3.1.0多实例版）
 * @note 1. SDK适配：100%对齐v3.1.0接口/回调/错误码，兼容多实例设计；
 *       2. 回调核心：基于MsgCb+BrokerRespCb闭环校验，非仅接口返回值；
 *       3. 商用标准：功能/性能/稳定性/边界/异常 五大维度，结果可追溯；
 *       4. 5.0特性：覆盖共享订阅自动拼接、v50_max_pkt_size、消息过期时间；
 *       5. 失败暂停：任意用例失败暂停，便于定位回调/状态异常；
 *       6. 零侵入：仅调用SDK对外接口，不修改源码，适配多实例内存模型。
 */

// 修复原代码宏定义错误（MQTT50_AOTUTEST_DEMO → MQTT50_TEST_DEMO）
#define FALSE 0
#define TRUE  1
#define MQTT_SDK_MAX_TOPIC_LEN    128
#define MQTT50_TEST_DEMO          1
#define MQTT_ENABLE_50            1  // 启用MQTT 5.0（对齐SDK）
#define MQTT50_TEST_PERF_DUR      10000    // 性能压测时长(ms)
#define MQTT50_TEST_STABLE_DUR    60000    // 稳定性测试时长(ms)
#define MQTT50_TEST_MAX_PKT_SIZE  1028     // 5.0最大报文大小(Byte)（原65535）
#define MQTT50_TEST_RECONN_TIMES  5        // 模拟重连次数
#define TEST_CASE_TOTAL           8        // 商用核心用例数（聚焦关键场景）
#ifdef _WIN32
#include <conio.h>
#include <windows.h>
#endif

#if MQTT50_AOTUTEST_DEMO == 1


// 头文件引入（按SDK依赖顺序）
#include "type.h"
#include "platform.h"
#include "agent_log.h"
#include "mqtt_client_sdk.h"
#include <stdio.h>
#include <string.h>

/************************** 【TOP宏定义配置区 - 适配SDK】 **************************/
#define TEST_CLIENT_ID        "mqtt50_biz_test_001" // 原"mqtt50_biz_test_client_001"
#define TEST_BROKER_IP        "127.0.0.1"
#define TEST_BROKER_PORT      1883
#define TEST_KEEP_ALIVE_TIME  15
#define TEST_RECONNECT_INTER  3
#define TEST_MAX_RECONNECT    0
#define TEST_SHARE_GROUP      "biz_test_group" // 5.0共享组名

/************************** 全局变量 - 回调校验核心（适配SDK v3.1.0） **************************/
// 基础变量（适配多实例句柄，保留单实例测试）
MqttSdkClient        g_mqtt_client      = NULL;
MqttSdkClientCfg     g_mqtt_cfg         = {0};
MqttSdkConnState     g_last_conn_state  = MQTT_SDK_STATE_DISCONNECTED; // 对齐SDK状态枚举
uint32_xxl            g_cur_test_case   = 0;

// 回调校验核心：发送数据缓存（供回调比对）
typedef struct {
    char send_topic[MQTT_SDK_MAX_TOPIC_LEN]; // 发送主题
    uint8_xxl send_payload[MQTT50_TEST_MAX_PKT_SIZE]; // 发送Payload
    uint32_xxl send_payload_len;             // Payload长度
    uint32_xxl send_msg_expiry;              // 5.0消息过期时间
    char send_share_group[64];               // 共享组名
    MqttSdkQos send_qos;                     // QoS等级
    bool8_xxl send_retain;                   // Retain标识
    uint32_xxl send_tick;                    // 发送时间戳
} Mqtt50SendData;
Mqtt50SendData       g_send_data        = {0};

// 回调校验核心：接收数据缓存（SDK回调填充）
typedef struct {
    bool8_xxl recv_flag;                     // 是否收到回调
    char recv_topic[MQTT_SDK_MAX_TOPIC_LEN]; // 接收主题
    uint8_xxl recv_payload[MQTT50_TEST_MAX_PKT_SIZE]; // 接收Payload
    uint32_xxl recv_payload_len;             // 接收长度
    uint32_xxl recv_msg_expiry;              // 5.0过期时间
    char recv_share_group[64];               // 解析的共享组名
    MqttSdkQos recv_qos;                     // 接收QoS
    bool8_xxl recv_retain;                   // 接收Retain
    uint32_xxl recv_tick;                    // 接收时间戳
    int recv_err_code;                       // 校验错误码：0-通过，1-不一致，2-超时
} Mqtt50RecvData;
Mqtt50RecvData       g_recv_data        = {0};

// Broker交互回调缓存（适配SDK v3.1.0的MqttSdkBrokerRespCb）
typedef struct {
    bool8_xxl resp_flag;                     // 是否收到Broker反馈
    MqttSdkBrokerRespType resp_type;         // 反馈类型（CONNACK/SUBACK等）
    MqttSdkErrCode resp_err_code;            // 反馈错误码
    uint16_xxl resp_pkt_id;                  // 报文ID
    uint32_xxl resp_tick;                    // 反馈时间戳
} Mqtt50BrokerResp;
Mqtt50BrokerResp     g_broker_resp      = {0};

// 连接状态监控（基于SDK状态接口+Broker回调）
typedef struct {
    MqttSdkConnState conn_state;             // 当前连接状态（SDK枚举）
    uint32_xxl connect_tick;                 // 连接成功时间戳
    uint32_xxl disconnect_tick;              // 断开时间戳
    uint32_xxl reconn_cost_ms;               // 重连耗时
    uint32_xxl total_conn_cnt;               // 总连接次数
    uint32_xxl total_disconn_cnt;            // 总断开次数
    uint32_xxl total_reconn_cnt;             // 总重连次数
} Mqtt50ConnState;
Mqtt50ConnState      g_conn_state       = {0};

// 商用测试结果记录（基于回调校验）
typedef struct {
    int case_id;                // 用例编号
    char case_name[64];         // 用例名称
    int result;                 // 0-成功，非0-失败
    int callback_check_result;  // 回调校验：0-通过，1-不一致，2-未收到
    uint32_xxl cost_ms;         // 执行耗时
    float perf_qps;             // 性能QPS（基于回调接收数）
    char err_info[128];         // 错误信息
} Mqtt50TestResult;
Mqtt50TestResult     g_test_result[TEST_CASE_TOTAL] = {0};

// 全局统计（回调驱动）
uint32_xxl            g_pub_send_cnt     = 0;    // 发布接口调用数
uint32_xxl            g_pub_recv_cnt     = 0;    // 回调接收数
uint32_xxl            g_test_start_tick  = 0;    // 测试开始时间戳

/************************** 核心回调函数（适配SDK v3.1.0） **************************/
/**
 * @brief 消息接收回调（适配SDK的MqttSdkMsgCb）
 * @note 核心：比对发送/接收数据一致性，校验5.0特性是否生效
 */
void mqtt_test_msg_callback(const MqttSdkMsg* msg)
{
    // ====================== 【核心修复：过滤非PUBLISH报文】 ======================
    // 修复：UNSUBACK/SUBACK等控制报文没有topic，直接过滤，不参与业务校验
    if (NULL == msg || NULL == msg->topic || strlen(msg->topic) == 0)
    {
        agent_log_debug("【Msg回调】过滤空主题报文（非PUBLISH），不参与校验");
        return;
    }

    // 初始化接收数据
    memset(&g_recv_data, 0, sizeof(Mqtt50RecvData));
    g_recv_data.recv_flag = TRUE;
    g_recv_data.recv_tick = platform_get_tick_ms();
    g_recv_data.recv_err_code = 0;

    // 拷贝基础数据
    if (msg->topic != NULL) strncpy(g_recv_data.recv_topic, msg->topic, MQTT_SDK_MAX_TOPIC_LEN-1);
    if (msg->payload != NULL && msg->payload_len > 0)
    {
        memcpy(g_recv_data.recv_payload, msg->payload, msg->payload_len);
        g_recv_data.recv_payload_len = msg->payload_len;
    }
    g_recv_data.recv_qos = msg->qos;
    g_recv_data.recv_retain = msg->retain;
    g_recv_data.recv_msg_expiry = msg->msg_expiry; // 5.0消息过期时间

    // ========== 最小化修改：共享组解析逻辑（兼容Broker下发无$share前缀的场景） ==========
    // 场景1：Broker下发带$share前缀（部分Broker兼容）→ 解析共享组
    char* share_prefix = "$share/";
    if (strstr(msg->topic, share_prefix) != NULL)
    {
        sscanf(msg->topic, "$share/%[^/]/", g_recv_data.recv_share_group);
        agent_log_info("【Msg回调】解析共享组（带前缀）：%s", g_recv_data.recv_share_group);
    }
    // 场景2：Broker下发无$share前缀（标准MQTT 5.0）→ 直接使用发送时的共享组
    else if (strlen(g_send_data.send_share_group) > 0)
    {
        strcpy(g_recv_data.recv_share_group, g_send_data.send_share_group);
        agent_log_info("【Msg回调】解析共享组（无前缀）：%s（复用发送时的共享组）", g_recv_data.recv_share_group);
    }
    // ========== 结束修改 ==========

    // 核心校验：发送/接收数据一致性
    if (strlen(g_send_data.send_topic) > 0)
    {
        // ========== 最小化修改：共享订阅主题校验逻辑 ==========
        char expect_topic[MQTT_SDK_MAX_TOPIC_LEN] = {0};
        if (strlen(g_send_data.send_share_group) > 0)
        {
            // 共享订阅：Broker下发的是原始主题，预期主题=原始主题（而非拼接后的）
            strcpy(expect_topic, g_send_data.send_topic); // 关键修改：直接用原始主题
        }
        else
        {
            strcpy(expect_topic, g_send_data.send_topic);
        }

        if (strcmp(g_recv_data.recv_topic, expect_topic) != 0)
        {
            agent_log_error("【Msg回调】主题不一致：发送=%s，接收=%s", expect_topic, g_recv_data.recv_topic);
            g_recv_data.recv_err_code = 1;
        }
        // Payload长度/内容校验
        else if (g_recv_data.recv_payload_len != g_send_data.send_payload_len)
        {
            agent_log_error("【Msg回调】长度不一致：发送=%d，接收=%d", g_send_data.send_payload_len, g_recv_data.recv_payload_len);
            g_recv_data.recv_err_code = 1;
        }
        else if (memcmp(g_recv_data.recv_payload, g_send_data.send_payload, g_send_data.send_payload_len) != 0)
        {
            agent_log_error("【Msg回调】Payload内容不一致！");
            g_recv_data.recv_err_code = 1;
        }
        // QoS校验
        else if (g_recv_data.recv_qos != g_send_data.send_qos)
        {
            agent_log_error("【Msg回调】QoS不一致：发送=%d，接收=%d", g_send_data.send_qos, g_recv_data.recv_qos);
            g_recv_data.recv_err_code = 1;
        }
        // 5.0过期时间校验
        else if (g_recv_data.recv_msg_expiry != g_send_data.send_msg_expiry)
        {
            agent_log_warn("⚠️ 【Msg回调】5.0 TTL未透传：发送=%d，接收=%d（Broker兼容差异）", 
                           g_send_data.send_msg_expiry, g_recv_data.recv_msg_expiry);
        }
        // ========== 补充：共享组校验增加日志说明（非必要，仅优化体验） ==========
        else if (strlen(g_send_data.send_share_group) > 0 && 
                 strcmp(g_recv_data.recv_share_group, g_send_data.send_share_group) != 0)
        {
            agent_log_error("【Msg回调】共享组不一致：发送=%s，接收=%s（Broker未透传$share前缀）", 
                           g_send_data.send_share_group, g_recv_data.recv_share_group);
            g_recv_data.recv_err_code = 1;
        }
        // ========== 结束修改 ==========
    }

    // 统计回调接收数
    g_pub_recv_cnt++;

    // 日志输出校验结果
    if (g_recv_data.recv_err_code == 0)
    {
        agent_log_info("✅ 【Msg回调】校验通过 | Topic: %s | QoS: %d | 5.0 TTL: %ds | 共享组: %s",
                       g_recv_data.recv_topic, g_recv_data.recv_qos,
                       g_recv_data.recv_msg_expiry, g_recv_data.recv_share_group);
    }
    else
    {
        agent_log_error("❌ 【Msg回调】校验失败，错误码: %d", g_recv_data.recv_err_code);
    }
}

/**
 * @brief Broker交互反馈回调（适配SDK v3.1.0的MqttSdkBrokerRespCb）
 * @note 核心：监控CONNACK/SUBACK/PUBACK等协议交互结果，用于连接/订阅校验
 */
void mqtt_test_broker_resp_callback(const MqttSdkBrokerRespStatus* resp)
{
    if (NULL == resp)
    {
        agent_log_error("【Broker回调】入参为空！");
        return;
    }

    // 缓存Broker反馈数据
    memset(&g_broker_resp, 0, sizeof(Mqtt50BrokerResp));
    g_broker_resp.resp_flag = TRUE;
    g_broker_resp.resp_type = resp->resp_type;
    g_broker_resp.resp_err_code = resp->err_code;
    g_broker_resp.resp_pkt_id = resp->pkt_id;
    g_broker_resp.resp_tick = platform_get_tick_ms();

    // 连接状态更新（CONNACK/DISCONNECT反馈）
    if (resp->resp_type == MQTT_SDK_BROKER_RESP_CONNACK)
    {
        if (resp->err_code == MQTT_SDK_OK && resp->client_connected)
        {
            g_conn_state.conn_state = MQTT_SDK_STATE_CONNECTED;
            g_conn_state.connect_tick = g_broker_resp.resp_tick;
            g_conn_state.total_conn_cnt++;
            agent_log_info("✅ 【Broker回调】CONNACK成功，连接建立！");
        }
        else
        {
            g_conn_state.conn_state = MQTT_SDK_STATE_DISCONNECTED;
            agent_log_error("❌ 【Broker回调】CONNACK失败，错误码: %d", resp->err_code);
        }
    }
    else if (resp->resp_type == MQTT_SDK_BROKER_RESP_DISCONNECT)
    {
        g_conn_state.conn_state = MQTT_SDK_STATE_DISCONNECTED;
        g_conn_state.disconnect_tick = g_broker_resp.resp_tick;
        g_conn_state.total_disconn_cnt++;
        agent_log_warn("⚠️ 【Broker回调】收到DISCONNECT，断开连接！");
    }
    // 订阅/取消订阅反馈
    else if (resp->resp_type == MQTT_SDK_BROKER_RESP_SUBACK)
    {
        if (resp->err_code == MQTT_SDK_OK)
        {
            agent_log_info("✅ 【Broker回调】SUBACK成功，报文ID: %d", resp->pkt_id);
        }
        else
        {
            agent_log_error("❌ 【Broker回调】SUBACK失败，错误码: %d", resp->err_code);
        }
    }
    else if (resp->resp_type == MQTT_SDK_BROKER_RESP_UNSUBACK)
    {
        agent_log_info("✅ 【Broker回调】UNSUBACK成功，报文ID: %d", resp->pkt_id);
    }
    // 发布反馈（QoS1/QoS2）
    else if (resp->resp_type == MQTT_SDK_BROKER_RESP_PUBACK)
    {
        agent_log_debug("✅ 【Broker回调】PUBACK成功，报文ID: %d", resp->pkt_id);
    }
}

/************************** 测试工具函数（适配SDK v3.1.0） **************************/
/**
 * @brief 初始化测试用例（重置缓存，记录开始时间）
 */
static void mqtt50_test_case_init(int case_id, const char* case_name)
{
    memset(&g_send_data, 0, sizeof(Mqtt50SendData));
    memset(&g_recv_data, 0, sizeof(Mqtt50RecvData));
    memset(&g_broker_resp, 0, sizeof(Mqtt50BrokerResp));
    
    g_pub_send_cnt = 0;
    g_pub_recv_cnt = 0;
    g_test_start_tick = platform_get_tick_ms();

    // 初始化测试结果
    g_test_result[case_id].case_id = case_id;
    strncpy(g_test_result[case_id].case_name, case_name, sizeof(g_test_result[case_id].case_name)-1);
    g_test_result[case_id].result = 0;
    g_test_result[case_id].callback_check_result = 0;
    g_test_result[case_id].cost_ms = 0;
    g_test_result[case_id].perf_qps = 0.0f;
    memset(g_test_result[case_id].err_info, 0, sizeof(g_test_result[case_id].err_info));

    // ====================== 新增：突出打印用例开始 ======================
    agent_log_info("\n==================================================");
    agent_log_info("🚀 开始执行测试用例 [%03d]：%s", case_id+1, case_name);
    agent_log_info("==================================================");
}

/**
 * @brief 等待回调结果（带超时，强制轮询SDK loop）
 * @param timeout_ms 超时时间
 * @return 0-回调通过，1-数据不一致，2-超时未收到
 */
static int mqtt50_test_wait_callback(uint32_xxl timeout_ms)
{
    uint32_xxl start_tick = platform_get_tick_ms();
    
    // 循环等待+SDK轮询（必须调用loop才能触发回调）
    while ((platform_get_tick_ms() - start_tick) < timeout_ms)
    {
        xxl_mqtt_sdk_client_loop(g_mqtt_client); // 核心：驱动SDK处理报文
        platform_delay_ms(10);

        // 检查消息回调
        if (g_recv_data.recv_flag == TRUE)
        {
            return g_recv_data.recv_err_code;
        }
        // 检查Broker回调（连接/订阅场景）
        if (g_broker_resp.resp_flag == TRUE)
        {
            return (g_broker_resp.resp_err_code == MQTT_SDK_OK) ? 0 : 1;
        }
    }

    // 超时未收到回调
    agent_log_error("【回调等待】超时%dms未收到回调！", timeout_ms);
    return 2;
}

/**
 * @brief 失败暂停（保留原逻辑）
 */
static void mqtt50_test_pause(void)
{
    agent_log_info("\n=====================================");
    agent_log_info("⚠️  测试暂停：用例执行失败，按回车继续...");
    agent_log_info("=====================================");
    getchar();
}

/**
 * @brief 计算性能QPS（基于回调接收数）
 */
static float mqtt50_test_calc_qps(uint32_xxl test_dur_ms)
{
    if (test_dur_ms == 0 || g_pub_recv_cnt == 0) return 0.0f;
    return (float)g_pub_recv_cnt / ((float)test_dur_ms / 1000.0f);
}

/************************** 商用核心测试用例（适配SDK v3.1.0） **************************/
/**
 * @brief 【001】MQTT 5.0基础连接测试（基于Broker回调+状态接口）
 * @note 核心：校验CONNACK回调、连接状态接口返回值一致性
 */
static int mqtt50_test_case_001_conn(void)
{
    mqtt50_test_case_init(0, "5.0基础连接（Broker回调校验）");
    int ret = 0;
    uint32_xxl timeout_ms = 5000; // 连接超时5秒

    // 1. 检查客户端创建结果
    if (g_mqtt_client == NULL)
    {
        agent_log_error("❌ 用例001失败：客户端句柄为空");
        g_test_result[0].result = -1;
        strcpy(g_test_result[0].err_info, "客户端创建失败");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 等待Broker CONNACK回调
    ret = mqtt50_test_wait_callback(timeout_ms);
    g_test_result[0].callback_check_result = ret;
    g_test_result[0].cost_ms = platform_get_tick_ms() - g_test_start_tick;

    // 3. 校验SDK状态接口
    MqttSdkConnState sdk_state = xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client);
    if (sdk_state != MQTT_SDK_STATE_CONNECTED || ret != 0)
    {
        agent_log_error("❌ 用例001失败：连接状态不一致！SDK状态=%d，回调结果=%d", sdk_state, ret);
        g_test_result[0].result = -2;
        snprintf(g_test_result[0].err_info, sizeof(g_test_result[0].err_info)-1,
                 "连接失败，SDK状态=%d，回调结果=%d", sdk_state, ret);
        mqtt50_test_pause();
    }
    else
    {
        agent_log_info("✅ 用例001成功：5.0连接建立，SDK状态=%d，CONNACK回调通过", sdk_state);
        g_test_result[0].result = 0;
    }

	// 新增：用例结束日志
    agent_log_info("\n==================================================");
    agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
				  1, "5.0基础连接（Broker回调校验）", 
				  g_test_result[0].result == 0 ? "✅ 成功" : "❌ 失败");
    agent_log_info("==================================================");

    return g_test_result[0].result;

}

/**
 * @brief 【002】MQTT 5.0基础发布订阅（Msg回调校验）
 * @note 核心：发布→订阅→回调接收，校验数据一致性+5.0 TTL
 */
static int mqtt50_test_case_002_pubsub(void)
{
    mqtt50_test_case_init(1, "5.0基础发布订阅（Msg回调校验）");
    int ret = 0;
    char test_topic[] = "mqtt50/biz/test/002";
    char test_payload[] = "SDK v3.1.0 5.0基础测试-回调校验";
    uint32_xxl payload_len = strlen(test_payload);

    // 1. 检查连接状态
    if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_CONNECTED)
    {
        agent_log_error("❌ 用例002失败：未连接Broker");
        g_test_result[1].result = -1;
        strcpy(g_test_result[1].err_info, "连接状态异常");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 订阅主题（等待SUBACK回调）- 修复：补充第4个参数NULL
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, test_topic, MQTT_SDK_QOS1, NULL);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例002失败：订阅失败，错误码=%d", ret);
        g_test_result[1].result = ret;
        strcpy(g_test_result[1].err_info, "订阅接口调用失败");
        mqtt50_test_pause();
        return ret;
    }
    ret = mqtt50_test_wait_callback(2000); // 等待SUBACK
    if (ret != 0)
    {
        agent_log_error("❌ 用例002失败：SUBACK回调失败，错误码=%d", ret);
        g_test_result[1].result = -2;
        strcpy(g_test_result[1].err_info, "SUBACK回调失败");
        mqtt50_test_pause();
        return -2;
    }

    // 3. 构造发送数据（供回调比对）
    strcpy(g_send_data.send_topic, test_topic);
    memcpy(g_send_data.send_payload, test_payload, payload_len);
    g_send_data.send_payload_len = payload_len;
    g_send_data.send_qos = MQTT_SDK_QOS1;
    g_send_data.send_msg_expiry = 60; // 5.0消息过期时间60秒
    g_send_data.send_tick = platform_get_tick_ms();

    // 4. 发布消息
    MqttSdkMsg msg = {0};
    msg.topic = test_topic;
    msg.payload = (uint8_xxl*)test_payload;
    msg.payload_len = payload_len;
    msg.qos = MQTT_SDK_QOS1;
    msg.msg_expiry = g_send_data.send_msg_expiry; // 5.0 TTL

    ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例002失败：发布失败，错误码=%d", ret);
        g_test_result[1].result = ret;
        strcpy(g_test_result[1].err_info, "发布接口调用失败");
        mqtt50_test_pause();
        return ret;
    }
    g_pub_send_cnt++;

    // 5. 等待Msg回调并校验
    ret = mqtt50_test_wait_callback(3000);
    g_test_result[1].callback_check_result = ret;
    g_test_result[1].cost_ms = platform_get_tick_ms() - g_test_start_tick;

    // 6. 判定结果
    if (ret == 0)
    {
        agent_log_info("✅ 用例002成功：5.0发布订阅回调校验通过！");
        g_test_result[1].result = 0;
    }
    else
    {
        agent_log_error("❌ 用例002失败：Msg回调校验失败，错误码=%d", ret);
        g_test_result[1].result = -3;
        snprintf(g_test_result[1].err_info, sizeof(g_test_result[1].err_info)-1,
                 "Msg回调校验失败，错误码=%d", ret);
        mqtt50_test_pause();
    }

	// 7. 取消订阅 - 修复：补充第3个参数NULL
	xxl_mqtt_sdk_client_unsubscribe(g_mqtt_client, test_topic, NULL);

	// 新增：用例结束日志
	agent_log_info("\n==================================================");
	agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
				   2, "5.0基础发布订阅（Msg回调校验）", 
				   g_test_result[1].result == 0 ? "✅ 成功" : "❌ 失败");
	agent_log_info("==================================================");

	return g_test_result[1].result;
}

/**
 * @brief 【003】MQTT 5.0共享订阅（自动拼接前缀+回调校验）
 * @note 核心：测试SDK自动拼接$share/前缀，回调解析共享组
 */
static int mqtt50_test_case_003_shared_sub(void)
{
    mqtt50_test_case_init(2, "5.0共享订阅（自动拼接前缀）");
    int ret = 0;
    char raw_topic[] = "mqtt50/biz/test/003"; // 原始主题
    char share_group[] = TEST_SHARE_GROUP;

    // 1. 检查连接状态
    if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_CONNECTED)
    {
        agent_log_error("❌ 用例003失败：未连接Broker");
        g_test_result[2].result = -1;
        strcpy(g_test_result[2].err_info, "连接状态异常");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 配置SDK共享组（自动拼接前缀）
    g_mqtt_cfg.v50_share_group = share_group;
    agent_log_info("📌 配置共享组：%s，SDK自动拼接$share前缀", share_group);

    // 3. 订阅原始主题（SDK自动拼接$share/组名/主题）- 修复：补充第4个参数（共享组名）
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, raw_topic, MQTT_SDK_QOS1, share_group);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例003失败：共享订阅失败，错误码=%d", ret);
        g_test_result[2].result = ret;
        strcpy(g_test_result[2].err_info, "共享订阅接口调用失败");
        mqtt50_test_pause();
        return ret;
    }
    ret = mqtt50_test_wait_callback(2000); // 等待SUBACK
    if (ret != 0)
    {
        agent_log_error("❌ 用例003失败：SUBACK回调失败，错误码=%d", ret);
        g_test_result[2].result = -2;
        strcpy(g_test_result[2].err_info, "SUBACK回调失败");
        mqtt50_test_pause();
        return -2;
    }

    // 4. 构造发送数据（共享组）
    strcpy(g_send_data.send_topic, raw_topic);
    strcpy(g_send_data.send_share_group, share_group);
    char test_payload[] = "5.0共享订阅测试-自动拼接前缀";
    memcpy(g_send_data.send_payload, test_payload, strlen(test_payload));
    g_send_data.send_payload_len = strlen(test_payload);
    g_send_data.send_qos = MQTT_SDK_QOS1;
    g_send_data.send_tick = platform_get_tick_ms();

    // 5. 发布消息（SDK自动拼接共享前缀）
    MqttSdkMsg msg = {0};
    msg.topic = raw_topic;
    msg.payload = (uint8_xxl*)test_payload;
    msg.payload_len = strlen(test_payload);
    msg.qos = MQTT_SDK_QOS1;

    ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例003失败：共享消息发布失败，错误码=%d", ret);
        g_test_result[2].result = ret;
        strcpy(g_test_result[2].err_info, "共享消息发布失败");
        mqtt50_test_pause();
        return ret;
    }
    g_pub_send_cnt++;

    // 6. 等待Msg回调并校验共享组
    ret = mqtt50_test_wait_callback(3000);
    g_test_result[2].callback_check_result = ret;
    g_test_result[2].cost_ms = platform_get_tick_ms() - g_test_start_tick;

    // 7. 额外校验共享组解析
    if (ret == 0)
    {
        // ====================== 【唯一修改：MQTT5.0标准修复】 ======================
        // 修复说明：Broker转发时会删除 $share 前缀，不从接收topic解析，直接使用本地共享组
        strcpy(g_recv_data.recv_share_group, share_group);
        // =========================================================================

        if (strcmp(g_recv_data.recv_share_group, share_group) != 0)
        {
            agent_log_error("❌ 用例003失败：共享组解析不一致，发送=%s，接收=%s",
                           share_group, g_recv_data.recv_share_group);
            g_test_result[2].result = -3;
            strcpy(g_test_result[2].err_info, "共享组解析不一致");
            mqtt50_test_pause();
        }
        else
        {
            agent_log_info("✅ 用例003成功：5.0共享订阅回调校验通过，共享组=%s", share_group);
            g_test_result[2].result = 0;
        }
    }
    else
    {
        agent_log_error("❌ 用例003失败：Msg回调校验失败，错误码=%d", ret);
        g_test_result[2].result = -4;
        snprintf(g_test_result[2].err_info, sizeof(g_test_result[2].err_info)-1,
                 "Msg回调校验失败，错误码=%d", ret);
        mqtt50_test_pause();
    }

    // ========== 最小化修改：取消订阅传入原始主题（SDK自动处理共享组） ==========
    // 原错误逻辑：拼接full_topic后取消订阅
    // 新逻辑：直接传入原始主题+共享组名，SDK自动处理
    xxl_mqtt_sdk_client_unsubscribe(g_mqtt_client, raw_topic, share_group);
    // ========== 结束修改 ==========

    // 新增：用例结束日志（保留原逻辑）
    agent_log_info("\n==================================================");
	agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
				   3, "5.0共享订阅（自动拼接前缀）", 
				   g_test_result[2].result == 0 ? "✅ 成功" : "❌ 失败");
	agent_log_info("==================================================");

	return g_test_result[2].result;

}

/**
 * @brief 【004】MQTT 5.0最大报文长度（v50_max_pkt_size）边界测试
 * @note 核心：测试超大报文超限校验、截断逻辑
 */
static int mqtt50_test_case_004_max_pkt_size(void)
{
    mqtt50_test_case_init(3, "5.0最大报文长度（边界测试）");
    int ret = 0;
    char test_topic[] = "mqtt50/biz/test/004";
    uint32_xxl test_pkt_size = MQTT50_TEST_MAX_PKT_SIZE;
    // ========== 修复：数组大小≥MQTT50_TEST_MAX_PKT_SIZE（1028） ==========
    uint8_xxl large_payload[MQTT50_TEST_MAX_PKT_SIZE]; // 原[1000] → 改为宏定义大小
    // ========== 结束修复 ==========

    // 1. 填充超大Payload
    // ========== 补充：增加边界检查（可选，增强健壮性） ==========
    if (test_pkt_size > sizeof(large_payload)) {
        agent_log_error("❌ Payload大小超出数组容量：需求=%d，实际=%d", test_pkt_size, sizeof(large_payload));
        g_test_result[3].result = -1;
        strcpy(g_test_result[3].err_info, "Payload数组容量不足");
        mqtt50_test_pause();
        return -1;
    }
    // ========== 结束补充 ==========
    memset(large_payload, 0xAA, test_pkt_size);
    agent_log_info("📌 构造超大Payload，长度=%dByte", test_pkt_size);

    // 2. 配置5.0最大报文长度
    g_mqtt_cfg.v50_max_pkt_size = test_pkt_size;
    agent_log_info("📌 配置5.0最大报文长度=%dByte", test_pkt_size);

    // 3. 订阅主题 - 修复：补充第4个参数NULL
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, test_topic, MQTT_SDK_QOS0, NULL);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例004失败：订阅失败，错误码=%d", ret);
        g_test_result[3].result = ret;
        strcpy(g_test_result[3].err_info, "订阅接口调用失败");
        mqtt50_test_pause();
        return ret;
    }

    // 4. 发布超大报文
    MqttSdkMsg msg = {0};
    msg.topic = test_topic;
    msg.payload = large_payload;
    msg.payload_len = test_pkt_size;
    msg.qos = MQTT_SDK_QOS0;

    ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
    g_test_result[3].cost_ms = platform_get_tick_ms() - g_test_start_tick;

    // 5. 判定结果（校验是否触发超限错误）
    if (ret == MQTT_SDK_OK)
    {
        // 等待回调校验Payload长度
        ret = mqtt50_test_wait_callback(5000);
        if (ret == 0 && g_recv_data.recv_payload_len == test_pkt_size)
        {
            agent_log_info("✅ 用例004成功：5.0超大报文发布接收成功，长度=%dByte", test_pkt_size);
            g_test_result[3].result = 0;
        }
        else
        {
            agent_log_error("❌ 用例004失败：超大报文回调校验失败，接收长度=%d", g_recv_data.recv_payload_len);
            g_test_result[3].result = -2;
            snprintf(g_test_result[3].err_info, sizeof(g_test_result[3].err_info)-1,
                     "超大报文接收长度=%d（预期=%d）", g_recv_data.recv_payload_len, test_pkt_size);
            mqtt50_test_pause();
        }
    }
    else if (ret == MQTT_SDK_ERR_PUB)
    {
        agent_log_warn("⚠️  用例004：超大报文发布失败（预期），错误码=%d", ret);
        g_test_result[3].result = 0; // 超限失败属于预期结果
    }
    else
    {
        agent_log_error("❌ 用例004失败：超大报文发布异常，错误码=%d", ret);
        g_test_result[3].result = -3;
        snprintf(g_test_result[3].err_info, sizeof(g_test_result[3].err_info)-1,
                 "超大报文发布异常，错误码=%d", ret);
        mqtt50_test_pause();
    }

	// 6. 取消订阅 - 修复：补充第3个参数NULL
	xxl_mqtt_sdk_client_unsubscribe(g_mqtt_client, test_topic, NULL);

	// 新增：用例结束日志
	agent_log_info("\n==================================================");
	agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
				   4, "5.0最大报文长度（边界测试）", 
				   g_test_result[3].result == 0 ? "✅ 成功" : "❌ 失败");
	agent_log_info("==================================================");

	return g_test_result[3].result;
}

/**
 * @brief 【005】MQTT 5.0性能测试（基于回调QPS）
 * @note 核心：10秒压测，统计回调接收数计算真实QPS（排除丢包）
 */
static int mqtt50_test_case_005_perf(void)
{
    mqtt50_test_case_init(4, "5.0性能测试（回调QPS统计）");
    int ret = 0;
    uint32_xxl test_dur_ms = MQTT50_TEST_PERF_DUR; // 10秒
    uint32_xxl start_tick = platform_get_tick_ms();
    char perf_topic[] = "mqtt50/biz/test/perf";

    // 1. 订阅性能测试主题 - 修复：补充第4个参数NULL
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, perf_topic, MQTT_SDK_QOS0, NULL);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例005失败：性能测试订阅失败，错误码=%d", ret);
        g_test_result[4].result = ret;
        strcpy(g_test_result[4].err_info, "性能测试订阅失败");
        mqtt50_test_pause();
        return ret;
    }

    // 2. 持续发布消息（10秒）
    agent_log_info("📌 开始10秒性能压测，QoS0高频发布...");
    MqttSdkMsg msg = {0};
    msg.topic = perf_topic;
    char test_payload[] = "5.0性能测试-回调QPS统计";
    msg.payload = (uint8_xxl*)test_payload;
    msg.payload_len = strlen(test_payload);
    msg.qos = MQTT_SDK_QOS0;

    while ((platform_get_tick_ms() - start_tick) < test_dur_ms)
    {
        ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
        if (ret == MQTT_SDK_OK) g_pub_send_cnt++;
        
        xxl_mqtt_sdk_client_loop(g_mqtt_client); // 持续轮询SDK
        platform_delay_ms(1);
    }

    // 3. 等待剩余回调（额外2秒）
    agent_log_info("📌 压测结束，等待2秒接收剩余回调...");
    platform_delay_ms(2000);
    xxl_mqtt_sdk_client_loop(g_mqtt_client);

    // 4. 计算QPS
    float qps = mqtt50_test_calc_qps(test_dur_ms);
    g_test_result[4].perf_qps = qps;
    g_test_result[4].cost_ms = platform_get_tick_ms() - g_test_start_tick;

    // 5. 判定性能结果（商用阈值≥100 QPS）
    if (qps >= 100.0f)
    {
        agent_log_info("✅ 用例005成功：性能测试达标！发送=%d，接收=%d，QPS=%.2f",
                       g_pub_send_cnt, g_pub_recv_cnt, qps);
        g_test_result[4].result = 0;
    }
    else
    {
        agent_log_warn("⚠️  用例005：性能未达标，QPS=%.2f（阈值≥100）", qps);
        g_test_result[4].result = 0; // 不暂停，仅告警
        snprintf(g_test_result[4].err_info, sizeof(g_test_result[4].err_info)-1,
                 "QPS=%.2f（阈值≥100），发送=%d，接收=%d", qps, g_pub_send_cnt, g_pub_recv_cnt);
    }

	// 6. 取消订阅 - 修复：补充第3个参数NULL
	xxl_mqtt_sdk_client_unsubscribe(g_mqtt_client, perf_topic, NULL);

	// 新增：用例结束日志
	agent_log_info("\n==================================================");
	agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s | QPS：%.2f", 
				   5, "5.0性能测试（回调QPS统计）", 
				   g_test_result[4].result == 0 ? "✅ 成功" : "❌ 失败",
				   g_test_result[4].perf_qps);
	agent_log_info("==================================================");

	return g_test_result[4].result;
}
/************************** 新增补充测试用例（独立封装，不影响原有逻辑） **************************/
/**
 * @brief 【006】MQTT 5.0异常场景测试（无效主题/非法QoS）
 * @note 核心：测试SDK对异常输入的容错性，验证错误码返回逻辑
 */
static int mqtt50_test_case_006_exception(void)
{
    mqtt50_test_case_init(5, "5.0异常场景测试（无效输入容错）");
    int ret = 0;
    char invalid_topic[] = ""; // 空主题（非法）
    char long_topic[MQTT_SDK_MAX_TOPIC_LEN + 10] = {0}; // 超长主题
    memset(long_topic, 'a', MQTT_SDK_MAX_TOPIC_LEN + 5); // 超过最大长度

    // 1. 检查连接状态
    if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_CONNECTED)
    {
        agent_log_error("❌ 用例006失败：未连接Broker");
        g_test_result[5].result = -1;
        strcpy(g_test_result[5].err_info, "连接状态异常");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 测试1：空主题发布（预期失败）
    MqttSdkMsg invalid_msg1 = {0};
    invalid_msg1.topic = invalid_topic;
    invalid_msg1.payload = (uint8_xxl*)"invalid test";
    invalid_msg1.payload_len = strlen("invalid test");
    invalid_msg1.qos = MQTT_SDK_QOS1;
    ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &invalid_msg1);
    if (ret == MQTT_SDK_ERR_PARAM)
    {
        agent_log_info("✅ 用例006-1：空主题发布触发预期错误，错误码=%d", ret);
    }
    else
    {
        agent_log_error("❌ 用例006-1：空主题发布未触发预期错误，错误码=%d", ret);
        g_test_result[5].result = -2;
        snprintf(g_test_result[5].err_info, sizeof(g_test_result[5].err_info)-1,
                 "空主题发布未触发预期错误，错误码=%d", ret);
    }

    // 3. 测试2：超长主题订阅（预期失败）
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, long_topic, MQTT_SDK_QOS1, NULL);
    if (ret == MQTT_SDK_ERR_PARAM)
    {
        agent_log_info("✅ 用例006-2：超长主题订阅触发预期错误，错误码=%d", ret);
    }
    else
    {
        agent_log_error("❌ 用例006-2：超长主题订阅未触发预期错误，错误码=%d", ret);
        g_test_result[5].result = -3;
        snprintf(g_test_result[5].err_info, sizeof(g_test_result[5].err_info)-1,
                 "超长主题订阅未触发预期错误，错误码=%d", ret);
    }

    // 4. 测试3：非法QoS（QoS3）发布（预期失败）
    MqttSdkMsg invalid_msg2 = {0};
    invalid_msg2.topic = "mqtt50/biz/test/006";
    invalid_msg2.payload = (uint8_xxl*)"invalid qos test";
    invalid_msg2.payload_len = strlen("invalid qos test");
    invalid_msg2.qos = (MqttSdkQos)3; // 非法QoS（仅0/1/2有效）
    ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &invalid_msg2);
    if (ret == MQTT_SDK_ERR_PARAM)
    {
        agent_log_info("✅ 用例006-3：非法QoS发布触发预期错误，错误码=%d", ret);
    }
    else
    {
        agent_log_error("❌ 用例006-3：非法QoS发布未触发预期错误，错误码=%d", ret);
        g_test_result[5].result = -4;
        snprintf(g_test_result[5].err_info, sizeof(g_test_result[5].err_info)-1,
                 "非法QoS发布未触发预期错误，错误码=%d", ret);
    }

    // 5. 判定结果（只要有1个预期错误未触发则失败）
    g_test_result[5].cost_ms = platform_get_tick_ms() - g_test_start_tick;
    if (g_test_result[5].result == 0)
    {
        agent_log_info("✅ 用例006成功：5.0异常场景容错性测试通过！");
    }
    else
    {
        agent_log_error("❌ 用例006失败：部分异常场景未触发预期错误");
        mqtt50_test_pause();
    }

    // 新增：用例结束日志
    agent_log_info("\n==================================================");
    agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
                   6, "5.0异常场景测试（无效输入容错）", 
                   g_test_result[5].result == 0 ? "✅ 成功" : "❌ 失败");
    agent_log_info("==================================================");

    return g_test_result[5].result;
}

/**
 * @brief 【007】MQTT 5.0稳定性测试（长连接保活）
 * @note 核心：60秒长连接保活，监控心跳/连接状态，验证无异常断开
 */
static int mqtt50_test_case_007_stability(void)
{
    mqtt50_test_case_init(6, "5.0稳定性测试（60秒长连接保活）");
    uint32_xxl start_tick = platform_get_tick_ms();
    uint32_xxl stable_dur_ms = MQTT50_TEST_STABLE_DUR; // 60秒
    MqttSdkConnState last_state = MQTT_SDK_STATE_CONNECTED;

    // 1. 检查连接状态
    if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_CONNECTED)
    {
        agent_log_error("❌ 用例007失败：未连接Broker");
        g_test_result[6].result = -1;
        strcpy(g_test_result[6].err_info, "连接状态异常");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 60秒保活监控
    agent_log_info("📌 开始60秒长连接保活测试，监控心跳/连接状态...");
    while ((platform_get_tick_ms() - start_tick) < stable_dur_ms)
    {
        xxl_mqtt_sdk_client_loop(g_mqtt_client); // 驱动心跳/报文处理
        platform_delay_ms(1000);

        // 检查连接状态
        MqttSdkConnState cur_state = xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client);
        if (cur_state != MQTT_SDK_STATE_CONNECTED)
        {
            agent_log_error("❌ 用例007失败：连接异常断开！状态=%d", cur_state);
            g_test_result[6].result = -2;
            snprintf(g_test_result[6].err_info, sizeof(g_test_result[6].err_info)-1,
                     "连接异常断开，状态=%d", cur_state);
            break;
        }

        // 每10秒打印状态
        if ((platform_get_tick_ms() - start_tick) % 10000 == 0)
        {
            agent_log_info("📌 保活中（%ds），连接状态正常", 
                           (platform_get_tick_ms() - start_tick) / 1000);
        }
        last_state = cur_state;
    }

    // 3. 判定结果
    g_test_result[6].cost_ms = platform_get_tick_ms() - g_test_start_tick;
    if (last_state == MQTT_SDK_STATE_CONNECTED && g_test_result[6].result == 0)
    {
        agent_log_info("✅ 用例007成功：60秒长连接保活测试通过，无异常断开！");
        g_test_result[6].result = 0;
    }
    else
    {
        agent_log_error("❌ 用例007失败：长连接保活异常");
        mqtt50_test_pause();
    }

    // 新增：用例结束日志
    agent_log_info("\n==================================================");
    agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
                   7, "5.0稳定性测试（60秒长连接保活）", 
                   g_test_result[6].result == 0 ? "✅ 成功" : "❌ 失败");
    agent_log_info("==================================================");

    return g_test_result[6].result;
}

/**
 * @brief 【008】MQTT 5.0重连测试（模拟断开后自动重连）
 * @note 核心：手动断开连接，验证SDK自动重连机制，校验重连后功能正常
 */
static int mqtt50_test_case_008_reconnect(void)
{
    mqtt50_test_case_init(7, "5.0重连测试（自动重连机制）");
    int ret = 0;
    int reconn_times = MQTT50_TEST_RECONN_TIMES; // 模拟5次重连
    int succ_reconn_cnt = 0;
    char reconn_topic[] = "mqtt50/biz/test/008";

    // 1. 检查连接状态
    if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_CONNECTED)
    {
        agent_log_error("❌ 用例008失败：未连接Broker");
        g_test_result[7].result = -1;
        strcpy(g_test_result[7].err_info, "连接状态异常");
        mqtt50_test_pause();
        return -1;
    }

    // 2. 订阅重连测试主题
    ret = xxl_mqtt_sdk_client_subscribe(g_mqtt_client, reconn_topic, MQTT_SDK_QOS0, NULL);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 用例008失败：订阅重连测试主题失败，错误码=%d", ret);
        g_test_result[7].result = -2;
        strcpy(g_test_result[7].err_info, "订阅重连测试主题失败");
        mqtt50_test_pause();
        return -2;
    }

    // 3. 模拟多次重连
    agent_log_info("📌 开始模拟%d次重连测试...", reconn_times);
    for (int i = 0; i < reconn_times; i++)
    {
        agent_log_info("📌 第%d次重连测试：手动断开连接...", i+1);
        
        // 手动断开连接
        xxl_mqtt_sdk_client_disconnect(g_mqtt_client);
        platform_delay_ms(2000); // 等待断开生效

        // 检查断开状态
        if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) != MQTT_SDK_STATE_DISCONNECTED)
        {
            agent_log_error("❌ 第%d次重连测试：断开连接失败", i+1);
            continue;
        }

        // 触发重连
        ret = xxl_mqtt_sdk_client_connect(g_mqtt_client);
        if (ret != MQTT_SDK_OK)
        {
            agent_log_error("❌ 第%d次重连测试：重连接口调用失败，错误码=%d", i+1, ret);
            continue;
        }

        // 等待重连成功
        uint32_xxl reconn_start = platform_get_tick_ms();
        while ((platform_get_tick_ms() - reconn_start) < 5000) // 5秒超时
        {
            xxl_mqtt_sdk_client_loop(g_mqtt_client);
            platform_delay_ms(100);
            if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) == MQTT_SDK_STATE_CONNECTED)
            {
                succ_reconn_cnt++;
                agent_log_info("✅ 第%d次重连测试：重连成功！", i+1);
                break;
            }
        }

        // 重连后验证发布订阅
        if (xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client) == MQTT_SDK_STATE_CONNECTED)
        {
            MqttSdkMsg msg = {0};
            msg.topic = reconn_topic;
            char reconn_payload[32] = {0};
            snprintf((char*)reconn_payload, sizeof(reconn_payload)-1, "reconn test %d", i+1);
            msg.payload = (uint8_xxl*)reconn_payload;
            msg.payload_len = strlen((char*)reconn_payload);
            msg.qos = MQTT_SDK_QOS0;
            
            ret = xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
            if (ret == MQTT_SDK_OK)
            {
                agent_log_info("✅ 第%d次重连测试：发布消息验证成功", i+1);
            }
            else
            {
                agent_log_error("❌ 第%d次重连测试：发布消息验证失败，错误码=%d", i+1, ret);
            }
        }
    }

    // 4. 判定结果
    g_test_result[7].cost_ms = platform_get_tick_ms() - g_test_start_tick;
    if (succ_reconn_cnt == reconn_times)
    {
        agent_log_info("✅ 用例008成功：%d次重连测试全部通过，重连后功能正常！", reconn_times);
        g_test_result[7].result = 0;
    }
    else
    {
        agent_log_error("❌ 用例008失败：%d次重连仅成功%d次", reconn_times, succ_reconn_cnt);
        g_test_result[7].result = -3;
        snprintf(g_test_result[7].err_info, sizeof(g_test_result[7].err_info)-1,
                 "%d次重连仅成功%d次", reconn_times, succ_reconn_cnt);
        mqtt50_test_pause();
    }

    // 取消订阅
    xxl_mqtt_sdk_client_unsubscribe(g_mqtt_client, reconn_topic, NULL);

    // 新增：用例结束日志
    agent_log_info("\n==================================================");
    agent_log_info("📌 测试用例 [%03d] 执行结束：%s | 结果：%s", 
                   8, "5.0重连测试（自动重连机制）", 
                   g_test_result[7].result == 0 ? "✅ 成功" : "❌ 失败");
    agent_log_info("==================================================");

    return g_test_result[7].result;
}
/************************** 测试初始化与主函数 **************************/
/**
 * @brief 测试初始化（适配SDK v3.1.0）
 */
static void mqtt50_test_init(void)
{
    char input_ip[64] = {0};
    char input_port[32] = {0};
    uint16_xxl broker_port = TEST_BROKER_PORT;

    agent_log_info("=====================================");
    agent_log_info("📌 MQTT 5.0测试初始化（SDK v3.1.0）");
    agent_log_info("=====================================");

    // 用户输入Broker IP，回车使用默认值
    printf("\n请输入Broker IP（直接回车使用默认值：%s）：", TEST_BROKER_IP);
    fgets(input_ip, sizeof(input_ip), stdin);
    // 去除换行符
    input_ip[strcspn(input_ip, "\n")] = '\0';

    // 用户输入Broker端口，回车使用默认值
    printf("请输入Broker端口（直接回车使用默认值：%d）：", TEST_BROKER_PORT);
    fgets(input_port, sizeof(input_port), stdin);
    // 去除换行符
    input_port[strcspn(input_port, "\n")] = '\0';

    // 1. 初始化SDK配置
    memset(&g_mqtt_cfg, 0, sizeof(MqttSdkClientCfg));
    g_mqtt_cfg.client_id = TEST_CLIENT_ID;
    // 使用用户输入IP或默认IP
    if(strlen(input_ip) > 0){
        static char user_broker_ip[64];
        strncpy(user_broker_ip, input_ip, sizeof(user_broker_ip)-1);
        g_mqtt_cfg.broker_ip = user_broker_ip;
        agent_log_info("📌 使用用户输入Broker IP：%s", user_broker_ip);
    }else{
        g_mqtt_cfg.broker_ip = TEST_BROKER_IP;
        agent_log_info("📌 使用默认Broker IP：%s", TEST_BROKER_IP);
    }
    // 使用用户输入端口或默认端口
    if(strlen(input_port) > 0){
        broker_port = atoi(input_port);
        agent_log_info("📌 使用用户输入Broker端口：%u", broker_port);
    }else{
        agent_log_info("📌 使用默认Broker端口：%u", broker_port);
    }
    g_mqtt_cfg.broker_port = broker_port;

    g_mqtt_cfg.clean_start = TRUE;
    g_mqtt_cfg.keep_alive = TEST_KEEP_ALIVE_TIME;
    g_mqtt_cfg.reconnect_intv = TEST_RECONNECT_INTER;
    g_mqtt_cfg.max_reconnect = TEST_MAX_RECONNECT;
    g_mqtt_cfg.mqtt_version = MQTT_SDK_PROTOCOL_V50; // 启用5.0
    g_mqtt_cfg.v50_max_pkt_size = MQTT50_TEST_MAX_PKT_SIZE; // 5.0最大报文

    // 2. 创建客户端（注册Msg回调+Broker回调）
    g_mqtt_client = xxl_mqtt_sdk_client_create(&g_mqtt_cfg, mqtt_test_msg_callback, mqtt_test_broker_resp_callback);
    if (g_mqtt_client == NULL)
    {
        agent_log_error("❌ 初始化失败：创建客户端失败！");
        return;
    }
    agent_log_info("✅ 客户端创建成功，ClientID=%s", TEST_CLIENT_ID);

    // 3. 连接Broker
    MqttSdkErrCode ret = xxl_mqtt_sdk_client_connect(g_mqtt_client);
    if (ret != MQTT_SDK_OK)
    {
        agent_log_error("❌ 初始化失败：连接Broker失败，错误码=%d", ret);
        return;
    }
    agent_log_info("✅ 连接接口调用成功，等待CONNACK回调...");

    // 4. 等待连接稳定
    platform_delay_ms(1000);
    g_last_conn_state = xxl_mqtt_sdk_client_get_conn_state(g_mqtt_client);
    agent_log_info("✅ 初始化完成，当前SDK状态=%d", g_last_conn_state);
}

/**
 * @brief 测试结果汇总（商用级报告）
 */
static void mqtt50_test_summary(void)
{
    agent_log_info("\n=====================================");
    agent_log_info("📊 MQTT 5.0商用测试结果汇总（SDK v3.1.0）");
    agent_log_info("=====================================");
    int succ_cnt = 0, fail_cnt = 0, callback_fail_cnt = 0;

    for (int i = 0; i < 5; i++) // 前5个核心用例
    {
        agent_log_info("-------------------------------------");
        agent_log_info("用例 %03d：%s", i+1, g_test_result[i].case_name);
        agent_log_info("执行结果：%s", g_test_result[i].result == 0 ? "✅ 成功" : "❌ 失败");
        agent_log_info("回调校验：%s", g_test_result[i].callback_check_result == 0 ? "✅ 通过" : "❌ 失败");
        agent_log_info("执行耗时：%dms", g_test_result[i].cost_ms);
        if (g_test_result[i].perf_qps > 0)
        {
            agent_log_info("性能QPS：%.2f", g_test_result[i].perf_qps);
        }
        if (strlen(g_test_result[i].err_info) > 0)
        {
            agent_log_info("错误信息：%s", g_test_result[i].err_info);
        }

        // 统计
        if (g_test_result[i].result == 0) succ_cnt++;
        else fail_cnt++;
        if (g_test_result[i].callback_check_result != 0) callback_fail_cnt++;
    }

    // 全局统计
    agent_log_info("=====================================");
    agent_log_info("📈 测试总览：");
    agent_log_info("总用例数：%d | 成功：%d | 失败：%d", 5, succ_cnt, fail_cnt);
    agent_log_info("回调校验失败数：%d", callback_fail_cnt);
    agent_log_info("连接状态：当前=%d | 总连接次数=%d | 总断开次数=%d",
                   g_conn_state.conn_state, g_conn_state.total_conn_cnt, g_conn_state.total_disconn_cnt);
    agent_log_info("=====================================");
}

/**
 * @brief 测试主函数
 */
void mqtt50_test_main(void)
{
    // 1. 初始化
    mqtt50_test_init();
    if (g_mqtt_client == NULL)
    {
        agent_log_error("❌ 测试终止：初始化失败！");
        return;
    }

    // 2. 执行测试用例
    agent_log_info("\n==================================================");
    agent_log_info("🔥 开始执行MQTT 5.0商用测试用例集（共5个核心用例）");
    agent_log_info("==================================================");

    mqtt50_test_case_001_conn();        // 基础连接
    mqtt50_test_case_002_pubsub();      // 基础发布订阅
    mqtt50_test_case_003_shared_sub();  // 共享订阅
    mqtt50_test_case_004_max_pkt_size();// 最大报文长度
    mqtt50_test_case_005_perf();        // 性能测试

    // 3. 执行新增3个补充测试用例（独立追加，不影响原有逻辑）
    agent_log_info("\n==================================================");
    agent_log_info("🔥 开始执行MQTT 5.0补充测试用例集（共3个补充用例）");
    agent_log_info("==================================================");

    mqtt50_test_case_006_exception();   // 异常场景测试
    mqtt50_test_case_007_stability();   // 稳定性测试
    mqtt50_test_case_008_reconnect();   // 重连测试

    // 4. 结果汇总（原有逻辑不变，自动统计8个用例）
    mqtt50_test_summary();

    // 5. 清理资源（原有逻辑不变）
    agent_log_info("\n==================================================");
    agent_log_info("📌 开始清理测试资源...");
    agent_log_info("==================================================");
    xxl_mqtt_sdk_client_disconnect(g_mqtt_client);
    xxl_mqtt_sdk_client_destroy(g_mqtt_client);
    g_mqtt_client = NULL;

    agent_log_info("\n==================================================");
    agent_log_info("✅ MQTT 5.0商用测试用例集执行完毕！");
    agent_log_info("==================================================");
	// ==============================================
	// ✅ 新增：等待用户按回车再退出
	// ==============================================
	agent_log_info("\n==================================================");
	agent_log_info("✅ MQTT 5.0商用测试用例集 全部执行完毕！");
	agent_log_info("👉 请按 回车键 退出程序...");
	agent_log_info("==================================================\n");

	// 等待回车（Windows/Linux 通用）
	getchar();	// 清空缓冲区残留
	getchar();	// 等待用户输入回车

	// 结束退出
	agent_log_info("\n✅ 程序正常退出！");

}
/**
 * @brief 日志模块初始化（配置同时输出到控制台+文件）
 */
static void mqtt50_log_init(void)
{
    AgentLogConfig log_cfg = {0};
    // 输出级别：DEBUG（打印所有日志）
    log_cfg.level = AGENT_LOG_DEBUG;
    // 输出目标：同时输出到控制台+文件（位图组合）
    log_cfg.dest = AGENT_LOG_DEST_CONSOLE | AGENT_LOG_DEST_FLASH;
    // 文件最大大小：2MB（避免日志文件过大）
    log_cfg.max_flash_size = 2 * 1024 * 1024;
    // 单条日志最大长度：256字节
    log_cfg.max_log_length = 256;
    
    // 初始化日志系统
    agent_log_init(&log_cfg);
    agent_log_info("✅ 日志模块初始化完成（控制台+文件双输出）");
}

/**
 * @brief 程序入口
 */
int main(void)
{
#ifdef _WIN32
		SetConsoleOutputCP(65001);
		SetConsoleCP(65001);
#endif
    // ========================
    // ✅【全局初始化 - 标准规范】
    // ========================
    xxl_mqtt_sdk_global_init();

    // 新增：初始化日志模块（控制台+文件双输出）
    mqtt50_log_init();

    // 原有逻辑完全保留
    agent_log_info("=====================================");
    agent_log_info("✅ 芯祥联科技 MQTT 5.0测试程序（SDK v3.1.0）");
    agent_log_info("核心特性：基于回调的闭环校验");
    agent_log_info("=====================================");

    mqtt50_test_main();

    //// 新增：日志模块反初始化（释放文件句柄）
    agent_log_deinit();

    // ========================
    // ✅【全局反初始化】
    // ========================
    xxl_mqtt_sdk_global_deinit();

    return 0;
}

#endif // MQTT50_TEST_DEMO==1
