// Copyright (2025) Beijing Volcano Engine Technology Ltd.
// SPDX-License-Identifier: Apache-2.0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <stdbool.h>

#include <cJSON.h>
#include <esp_heap_caps.h>

// 确保在包含volc_rtc.h之前定义ENABLE_RTC_MODE
#ifndef ENABLE_RTC_MODE
#define ENABLE_RTC_MODE
#endif

#include "VolcEngineRTCLite.h"
#include "volc_rtc.h"
#include "volc_platform.h"
#include "util/volc_list.h"
#include "util/volc_log.h"
#include "util/volc_json.h"
#include "base/volc_base.h"
#include "base/volc_device_manager.h"

// 移除多余的ENABLE_RTC_MODE条件编译块，因为它已经在头文件中处理

#define MAGIC_CONTROL "ctrl"
#define MAGIC_CONV    "conv"
#define MAGIC_LENGTH 4
#define MAGIC_OFFSET 8
const char* interrupt_str = "{\"Command\":\"interrupt\"}";

typedef struct {
    bool b_pipeline_started;
    bool b_user_joined;
    bool b_channel_joined;
    bool b_first_keyframe_received;
    bool b_fini;
    bool b_audio_publish;
    bool b_video_publish;
    bool b_audio_subscribe;
    bool b_video_subscribe;
    char* p_appid;
    char* p_channel_name;
    char* p_user_id;
    char* p_remote_user_id;
    char* p_token;
    void* context;
    int audio_codec;
    volc_room_info_t info;
    volc_msg_cb message_callback;
    volc_data_cb data_callback;
    byte_rtc_engine_t rtc;
    byte_rtc_event_handler_t event_handler;
} rtc_impl_t;

static bool __is_first_keyframe_not_received(rtc_impl_t* rtc, int is_key_frame)
{
    return (!rtc->b_first_keyframe_received && !is_key_frame);
}

static int _build_binary_message(const char* magic, const char* message, 
                        uint8_t** out_buf, size_t* out_len) {
    size_t magic_len = strlen(magic);
    size_t msg_len = strlen(message);
    
    // 分配内存：魔术字 + 4字节长度 + 消息内容
    *out_len = magic_len + 4 + msg_len;
    *out_buf = (uint8_t*)hal_malloc(*out_len);
    if (!*out_buf) {
        LOGE("hal_malloc failed");
        return -1;
    }
    
    // 填充魔术字
    memcpy(*out_buf, magic, magic_len);
    
    // 以大端序填充长度
    uint8_t* len_ptr = *out_buf + magic_len;
    len_ptr[0] = (uint8_t)((msg_len >> 24) & 0xFF); // 最高位字节
    len_ptr[1] = (uint8_t)((msg_len >> 16) & 0xFF);
    len_ptr[2] = (uint8_t)((msg_len >> 8)  & 0xFF);
    len_ptr[3] = (uint8_t)(msg_len & 0xFF);         // 最低位字节
    
    // 填充消息内容
    memcpy(*out_buf + magic_len + 4, message, msg_len);
    
    return 0;
}

static int __rtc_start(rtc_impl_t* rtc, volc_rtc_option_t* option)
{
    byte_rtc_room_options_t room_opt = {0};
    if (!rtc || !option) {
        LOGE("rtc or option is NULL");
        return -1;
    }
    if (!option->p_channel_name || !option->p_uid || !option->p_token) {
        LOGE("invalid rtc option: channel(%p) uid(%p) token(%p)", option->p_channel_name, option->p_uid, option->p_token);
        return -1;
    }
    if (strlen(option->p_channel_name) == 0 || strlen(option->p_uid) == 0 || strlen(option->p_token) == 0) {
        LOGE("invalid rtc option: empty field");
        return -1;
    }

    room_opt.auto_publish_audio = rtc->b_audio_publish;
    room_opt.auto_publish_video = rtc->b_video_publish;
    room_opt.auto_subscribe_audio = rtc->b_audio_subscribe;
    room_opt.auto_subscribe_video = rtc->b_video_subscribe;
    
    // 记录内存使用情况
    size_t heap_free_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
    size_t spiram_free_before = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
    
    LOGI("Joining channel: %s, uid: %s, token: %s, vpub: %d, vsub: %d, apub: %d, asub: %d", 
         option->p_channel_name, option->p_uid, option->p_token, 
         (int)room_opt.auto_publish_video, (int)room_opt.auto_subscribe_video, 
         (int)room_opt.auto_publish_audio, (int)room_opt.auto_subscribe_audio);
    LOGI("Memory before byte_rtc_join_room - Heap: %u bytes, SPIRAM: %u bytes", 
         (unsigned)heap_free_before, (unsigned)spiram_free_before);
    
    int ret = byte_rtc_join_room(rtc->rtc, option->p_channel_name, option->p_uid, option->p_token, &room_opt);
    
    // 记录内存使用情况
    size_t heap_free_after = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
    size_t spiram_free_after = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
    
    LOGI("Memory after byte_rtc_join_room - Heap: %u bytes (change: %d), SPIRAM: %u bytes (change: %d)", 
         (unsigned)heap_free_after, (int)(heap_free_after - heap_free_before), 
         (unsigned)spiram_free_after, (int)(spiram_free_after - spiram_free_before));
    
    if (ret != 0) {
        LOGE("Failed to join room: %d", ret);
        return ret;
    }
    rtc->b_pipeline_started = true;
    
    rtc->p_channel_name = strdup(option->p_channel_name);
    if (!rtc->p_channel_name) {
        LOGE("Failed to allocate memory for channel name");
        return -1;
    }
    rtc->p_user_id = strdup(option->p_uid);
    if (!rtc->p_user_id) {
        LOGE("Failed to allocate memory for user ID");
        HAL_SAFE_FREE(rtc->p_channel_name);
        return -1;
    }

    return 0;
}

static void __rtc_stop(rtc_impl_t* rtc)
{
    if (!rtc) {
        LOGE("rtc instance is NULL");
        return;
    }
    if (!rtc->b_pipeline_started) {
        LOGI("pipeline not started");
        return;
    }

    int ret = byte_rtc_leave_room(rtc->rtc, rtc->p_channel_name);
    if (ret != 0) {
        LOGE("Failed to leave room: %d", ret);
        return;
    }
    rtc->b_pipeline_started = false;
    HAL_SAFE_FREE(rtc->p_channel_name);

    return;
}

// static void __send_message_2_user(rtc_impl_t* rtc, volc_msg_t* msg)
// {
//     if (rtc->message_callback) {
//         rtc->message_callback(rtc->context, msg);
//     }
// }

static void __send_data_2_user(rtc_impl_t* rtc, const void* data, int data_len, volc_data_info_t* info) {
    // 添加详细的参数验证，确保回调函数的安全调用
    if (!rtc) {
        LOGE("__send_data_2_user: rtc is NULL");
        return;
    }
    
    if (!rtc->data_callback) {
        // 没有注册回调函数，这是正常情况，不记录错误
        return;
    }
    
    if (!data) {
        LOGE("__send_data_2_user: data is NULL");
        return;
    }
    
    if (data_len <= 0) {
        LOGE("__send_data_2_user: data_len is <= 0");
        return;
    }
    
    if (!info) {
        LOGE("__send_data_2_user: info is NULL");
        return;
    }
    
    // 调用数据回调函数
    rtc->data_callback(rtc->context, data, data_len, info);
}

// static void _register_message_router(rtc_impl_t* rtc, volc_msg_cb callback)
// {
//     rtc->message_callback = callback;
// }

static void _send_message_2_user(rtc_impl_t* rtc, volc_msg_t* msg)
{
    if (rtc->message_callback) {
        rtc->message_callback(rtc->context, msg);
    }
}

static bool _is_target_message(const uint8_t* message, int size, const char* target) {
    if (message == NULL || target == NULL || size < MAGIC_LENGTH) {
        return false;
    }
    return memcmp(message, target, MAGIC_LENGTH) == 0;
}

static int _on_conversion_status_message_parsed(const char* json, int len) {
    int c = -1;
    char* buf = (char*)hal_malloc(len + 1);
    if (!buf) return c;
    memcpy(buf, json, len);
    buf[len] = '\0';
    cJSON *root = cJSON_Parse(buf);
    if (root != NULL) {
        volc_json_read_int(root, "Stage.Code", &c);
        cJSON_Delete(root);
    }
    hal_free(buf);
    return c;
}

static void _on_join_channel_success(byte_rtc_engine_t engine, const char* channel, int elapsed_ms, bool rejoin)
{
    volc_msg_t msg = {0};
    LOGI("join channel success %s elapsed %d ms\n", channel, elapsed_ms);
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);

    rtc->b_first_keyframe_received = false;
    rtc->b_channel_joined = true;

    msg.code = VOLC_MSG_CONNECTED;
    _send_message_2_user(rtc, &msg);
};

static void _on_user_joined(byte_rtc_engine_t engine, const char* channel, const char* user_name, int elapsed_ms)
{
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_msg_t msg = {0};
    LOGI("remote user joined %s:%s elapsed %d ms\n", channel, user_name, elapsed_ms);

    rtc->b_user_joined = true;
    
    // 先释放旧的内存
    HAL_SAFE_FREE(rtc->p_remote_user_id);
    
    // 分配新内存并检查结果
    char* temp = strdup(user_name);
    if (temp) {
        rtc->p_remote_user_id = temp;
    } else {
        LOGE("Failed to allocate memory for remote user ID");
    }

    msg.code = VOLC_MSG_USER_JOINED;
    _send_message_2_user(rtc, &msg);
};

static void _on_user_offline(byte_rtc_engine_t engine, const char* channel, const char* user_name, int reason)
{
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_msg_t msg = {0};
    LOGI("remote user offline %s:%s reason %d\n", channel, user_name, reason);
    rtc->b_user_joined = false;
    
    // 清理远程用户ID，避免内存泄漏
    HAL_SAFE_FREE(rtc->p_remote_user_id);

    msg.code = VOLC_MSG_USER_OFFLINE;
    _send_message_2_user(rtc, &msg);
};

static void _on_user_mute_audio(byte_rtc_engine_t engine, const char* channel, const char* user_name, int muted)
{
    LOGD("remote user mute audio  %s:%s %d\n", channel, user_name, muted);
};

static void _on_user_mute_video(byte_rtc_engine_t engine, const char* channel, const char* user_name, int muted)
{
    LOGD("remote user mute video  %s:%s %d\n", channel, user_name, muted);
};

static void _on_audio_data(byte_rtc_engine_t engine, const char* channel, const char* user_name, uint16_t sent_ts, audio_data_type_e data_type,
                            const void* data_ptr, size_t data_len, const uint8_t* extra_info, size_t extra_info_size)
{
    // 添加详细的参数验证，防止空指针和无效数据导致崩溃
    if (!engine) {
        LOGE("_on_audio_data: engine is NULL");
        return;
    }
    
    if (!channel) {
        LOGE("_on_audio_data: channel is NULL");
        return;
    }
    
    if (!user_name) {
        LOGE("_on_audio_data: user_name is NULL");
        return;
    }
    
    if (!data_ptr) {
        LOGE("_on_audio_data: data_ptr is NULL");
        return;
    }
    
    if (data_len == 0) {
        LOGE("_on_audio_data: data_len is 0");
        return;
    }
    
    volc_data_info_t info = {0};
    rtc_impl_t* rtc = (rtc_impl_t*)byte_rtc_get_user_data(engine);

    if (NULL == rtc) {
        LOGE("_on_audio_data: rtc instance is NULL");
        return;
    }
    
    if (!rtc->b_pipeline_started) {
        LOGE("_on_audio_data: pipeline not started");
        return;
    }
    
    if (!rtc->b_channel_joined) {
        LOGE("_on_audio_data: channel not joined");
        return;
    }
    
    if (!rtc->b_user_joined) {
        LOGE("_on_audio_data: user not joined");
        return;
    }
    
    info.type = VOLC_DATA_TYPE_AUDIO;
    info.info.audio.data_type = (volc_audio_data_type_e) data_type;
    // info.info.audio.sent_ts = sent_ts;
    
    // 限制数据大小，防止内存溢出
    if (data_len > 16384) { // 16KB的合理限制
        LOGW("_on_audio_data: data_len too large (%zu), truncating to 16KB", data_len);
        data_len = 16384;
    }
    
    __send_data_2_user(rtc, data_ptr, data_len, &info);
};

static void _on_video_data(byte_rtc_engine_t engine, const char* channel, const char* user_name, uint16_t sent_ts, video_data_type_e codec,
                           int is_key_frame, const void* data_ptr, size_t data_len)
{
    volc_data_info_t info = {0};
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);

    if (NULL == rtc || !rtc->b_pipeline_started || !rtc->b_channel_joined || !rtc->b_user_joined) {
        LOGD("pipeline not started or channel not joined or user not joined");
        return;
    }

    if (__is_first_keyframe_not_received(rtc, is_key_frame)) {
        LOGD("first keyframe not received, request key frame");
        byte_rtc_request_video_key_frame(rtc->rtc, channel, user_name);
        return;
    }

    rtc->b_first_keyframe_received = true;

    info.type = VOLC_DATA_TYPE_VIDEO;
    info.info.video.data_type = (volc_video_data_type_e) codec;
    __send_data_2_user(rtc, data_ptr, data_len, &info);
};

static void _on_channel_error(byte_rtc_engine_t engine, const char* channel, int code, const char* msg)
{
    volc_msg_t msg_data = {0};
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    LOGE("channel error %s:%d %s\n", channel, code, msg ? msg : "");
    LOGI("channel error heap_free=%u", (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
    msg_data.code = code;
    char* copied = NULL;
    if (msg) {
        size_t len = strnlen(msg, 1024);
        copied = (char*)hal_malloc(len + 1);
        if (copied) {
            memcpy(copied, msg, len);
            copied[len] = '\0';
            msg_data.data.msg = copied;
        }
    }
    _send_message_2_user(rtc, &msg_data);
    if (copied) {
        hal_free(copied);
    }
};

static void _on_global_error(byte_rtc_engine_t engine, int code, const char* message)
{
    volc_msg_t msg_data = {0};
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    rtc->b_channel_joined = false;

    rtc->b_first_keyframe_received = false;
    // 防御性判空: 火山 RTC SDK 在某些 ICE Agent 失败路径下会用 message=NULL 调用本回调,
    //   导致 printf("%s", NULL) → strlen(NULL) → LoadProhibited panic → 设备重启
    //   (idle ≥ 10 分钟后服务端 session 超时 / NAT 表过期等场景偶发触发)
    LOGI("global error %d %s\n", code, message ? message : "(null)");
    LOGI("global error heap_free=%u", (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
    msg_data.code = VOLC_MSG_DISCONNECTED;
    _send_message_2_user(rtc, &msg_data);
};

static void _on_key_frame_gen_req(byte_rtc_engine_t engine, const char* channel, const char* user_name)
{
    LOGI("remote req key frame %s:%s\n", channel, user_name);
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_msg_t msg_data = {0};
    msg_data.code = VOLC_MSG_KEY_FRAME_REQ;
    _send_message_2_user(rtc, &msg_data);
};

static void _on_target_bitrate_changed(byte_rtc_engine_t engine, const char* channel, uint32_t target_bps)
{
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_msg_t msg_data = {0};

    LOGD("target bitrate changed %s %d bps\n", channel, (int)target_bps);
    // TODO: do not send it to user
    msg_data.code = VOLC_MSG_TARGET_BITRATE_CHANGED;
    msg_data.data.target_bitrate = target_bps;
    _send_message_2_user(rtc, &msg_data);
};

static void _on_token_privilege_will_expire(byte_rtc_engine_t engine, const char* token)
{
    LOGI("\ntoken privilege will expire %s", token);
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_msg_t msg_data = {0};
    msg_data.code = VOLC_MSG_TOKEN_EXPIRED;
    // TODO: token?
    _send_message_2_user(rtc, &msg_data);
};

static void _on_message_received(byte_rtc_engine_t engine, const char* channel_name, const char* src, const uint8_t* message, int size, bool binary)
{
    int ret = 0;
    volc_msg_t msg = { 0 };
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    volc_data_info_t info = {0};
    info.type = VOLC_DATA_TYPE_MESSAGE;
    info.info.message.is_binary = binary;
    LOGI("message received channel=%s src=%s size=%d binary=%d free_heap=%u", channel_name, src, size, binary, (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));

    if (NULL == rtc || !rtc->b_pipeline_started || !rtc->b_channel_joined || !rtc->b_user_joined) {
        LOGE("pipeline not started or channel not joined or user not joined");
        return;
    }

    if (_is_target_message(message, size, MAGIC_CONV)) {
        if (size < MAGIC_OFFSET) {
            LOGW("conv message too short: %d", size);
            return;
        }
        int json_len = (message[4] << 24) | (message[5] << 16) | (message[6] << 8) | (message[7]);
        if (json_len <= 0 || size < (MAGIC_OFFSET + json_len)) {
            LOGW("conv message invalid length: %d size: %d", json_len, size);
            return;
        }
        const char* json_ptr = (const char*)(message + MAGIC_OFFSET);
        ret = _on_conversion_status_message_parsed(json_ptr, json_len);
        msg.code = VOLC_MSG_CONV_STATUS;
        msg.data.conv_status = ret;
        _send_message_2_user(rtc, &msg);
        return;
    }
    __send_data_2_user(rtc, message, size, &info);
};

static void _on_message_send_result(byte_rtc_engine_t engine, const char* channel_name, int64_t msgid, int error, const char* extencontent)
{
    LOGD("----------------------->MessageSendResult msg id %" PRId64 ", error %d, extencontent %s \n", msgid, error, extencontent);
};

static void _on_license_will_expire(byte_rtc_engine_t engine, int daysleft)
{
    LOGI("----------------------->license will expire in %d days \n", daysleft);
    volc_msg_t msg_data = {0};
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    msg_data.code = VOLC_MSG_LICENSE_EXPIRED;
    _send_message_2_user(rtc, &msg_data);
};

static void _on_fini_notify(byte_rtc_engine_t engine)
{
    rtc_impl_t* rtc = (rtc_impl_t*) byte_rtc_get_user_data(engine);
    rtc->b_fini = true;
}

static int __rtc_init(rtc_impl_t* engine, cJSON* p_config)
{
    int ret = 0;
    int video_codec = 0;
    int log_level = 0;
    int params_cnt = 0;
    cJSON* p_params = NULL;
    // 初始化结构体中的event_handler字段，避免局部变量导致的悬挂指针问题
    // 初始化结构体中的event_handler字段，避免局部变量导致的悬挂指针问题
    memset(&engine->event_handler, 0, sizeof(byte_rtc_event_handler_t));
    engine->event_handler.on_global_error = _on_global_error;
    engine->event_handler.on_join_room_success = _on_join_channel_success;
    engine->event_handler.on_room_error = _on_channel_error;
    engine->event_handler.on_user_joined = _on_user_joined;
    engine->event_handler.on_user_offline = _on_user_offline;
    engine->event_handler.on_user_mute_audio = _on_user_mute_audio;
    engine->event_handler.on_user_mute_video = _on_user_mute_video;
    engine->event_handler.on_audio_data = _on_audio_data;
    engine->event_handler.on_video_data = _on_video_data;
    engine->event_handler.on_key_frame_gen_req = _on_key_frame_gen_req;
    engine->event_handler.on_target_bitrate_changed = _on_target_bitrate_changed;
    engine->event_handler.on_token_privilege_will_expire = _on_token_privilege_will_expire;
    engine->event_handler.on_message_received = _on_message_received;
    engine->event_handler.on_message_send_result = _on_message_send_result;
    engine->event_handler.on_license_expire_warning = _on_license_will_expire;
    engine->event_handler.on_fini_notify = _on_fini_notify;
    ret = volc_json_read_int(p_config, "audio.codec", &engine->audio_codec);
    if (ret != 0 || engine->audio_codec < 0 || engine->audio_codec > AUDIO_CODEC_TYPE_G711U) {
        LOGE("volc_rtc_create: read audio_codec failed");
        return -1;
    }
    ret = volc_json_read_int(p_config, "video.codec", &video_codec);
    if (ret != 0 || video_codec < 0 || video_codec > VIDEO_CODEC_TYPE_BYTEVC1) {
        LOGE("volc_rtc_create: read video_codec failed");
        return -1;
    }
    ret = volc_json_read_int(p_config, "log_level", &log_level);
    if (ret != 0) {
       log_level = BYTE_RTC_LOG_LEVEL_WARN; // default log level
    }
    ret = volc_json_read_bool(p_config, "audio.publish", &engine->b_audio_publish);
    if (ret != 0) {
        engine->b_audio_publish = true; // default to publish audio
    }
    ret = volc_json_read_bool(p_config, "video.publish", &engine->b_video_publish);
    if (ret != 0) {
        engine->b_video_publish = false; // default to no publish video
    }
    ret = volc_json_read_bool(p_config, "audio.subscribe", &engine->b_audio_subscribe);
    if (ret != 0) {
        engine->b_audio_subscribe = true; // default to subscribe audio
    }
    ret = volc_json_read_bool(p_config, "video.subscribe", &engine->b_video_subscribe);
    if (ret != 0) {
        engine->b_video_subscribe = false; // default to no subscribe video
    }

    engine->rtc = byte_rtc_create(engine->p_appid, &engine->event_handler);
    if (!engine->rtc) {
        LOGE("volc_rtc_create: byte_rtc_create failed");
        return -1;
    }
    byte_rtc_set_user_data(engine->rtc, (void*) engine);
    byte_rtc_set_log_level(engine->rtc, log_level);
    
    ret = volc_json_read_object(p_config, "params", &p_params);
    if (0 == ret) {
        params_cnt = cJSON_GetArraySize(p_params);
        if (params_cnt > 0) {
            for (int i = 0; i < params_cnt; i++) {
                cJSON* p_param = cJSON_GetArrayItem(p_params, i);
                if (p_param && cJSON_IsString(p_param)) {
                    const char* param_str = cJSON_GetStringValue(p_param);
                    if (param_str && strlen(param_str) > 0) {
                        byte_rtc_set_params(engine->rtc, param_str);
                        LOGI("volc_rtc_create: set param[%d]: %s", i, param_str);
                    }
                }
            }
        }
        cJSON_Delete(p_params);
    }
    
    int init_ret = byte_rtc_init(engine->rtc);
    if (init_ret != 0) {
        LOGE("volc_rtc_create: byte_rtc_init failed with ret=%d", init_ret);
        return -1;
    }
    
    byte_rtc_set_audio_codec(engine->rtc, engine->audio_codec);
    byte_rtc_set_video_codec(engine->rtc, video_codec - 1); // -1 for default codec
    return 0;
}

volc_rtc_t volc_rtc_create(const char* appid, void* context, cJSON* p_config, volc_msg_cb message_callback, volc_data_cb data_callback)
{
    rtc_impl_t* rtc = (rtc_impl_t*) hal_calloc(1, sizeof(rtc_impl_t));
    if (!rtc) {
        LOGE("volc_rtc_create: malloc rtc failed");
        return NULL;
    }
    rtc->message_callback = message_callback;
    rtc->data_callback = data_callback;
    rtc->context = context;
    
    // 检查appid是否为空，如果为空则使用默认值
    const char* actual_appid = appid;
    if (!appid || strlen(appid) == 0) {
        LOGW("appid is empty, using default value");
        actual_appid = "default_appid";
    }
    
    rtc->p_appid = strdup(actual_appid);
    if (NULL == rtc->p_appid) {
        LOGE("malloc appid memory failed");
        goto err_out_label;
    }

    if (__rtc_init(rtc, p_config) != 0) {
        LOGE("volc_rtc_create: rtc init failed");
        goto err_out_label;
    }

    LOGD("rtc create success");
    return (volc_rtc_t)rtc;
err_out_label:
    HAL_SAFE_FREE(rtc->p_appid);
    HAL_SAFE_FREE(rtc);
    return NULL;
}

void volc_rtc_destroy(volc_rtc_t handle)
{
    rtc_impl_t* rtc = (rtc_impl_t*)handle;
    if (!rtc) {
        LOGE("rtc instance is NULL");
        return;
    }
    __rtc_stop(rtc);

    byte_rtc_fini(rtc->rtc);
    while (!rtc->b_fini) {
        usleep(1000 * 10);
    }
    byte_rtc_destroy(rtc->rtc);
    HAL_SAFE_FREE(rtc->p_channel_name);
    HAL_SAFE_FREE(rtc->p_user_id);
    HAL_SAFE_FREE(rtc->p_remote_user_id);
    HAL_SAFE_FREE(rtc->p_token);
    HAL_SAFE_FREE(rtc);
    LOGD("rtc destroy success");
}

// 新增：extra_params 用于传递额外的AgentConfig配置参数
int volc_rtc_start(volc_rtc_t rtc, const char* bot_id, volc_iot_info_t* iot_info, const char* extra_params) {
    // int ret = 0;
    volc_rtc_option_t *opt = NULL;
    rtc_impl_t* rtc_impl = (rtc_impl_t*) rtc;
    if (!rtc_impl) {
        LOGE("rtc instance is NULL");
        return -1;
    }
    if (!iot_info) {
        LOGE("iot_info is NULL");
        return -1;
    }
    // 检查bot_id是否为空，如果为空则使用默认值
    const char* actual_bot_id = bot_id;
    if (!bot_id || strlen(bot_id) == 0) {
        LOGW("bot_id is empty, using default value");
        actual_bot_id = "default_bot";
    }
    char* task_id = "test";
    LOGI("volc_rtc_start: bot_id=%s audio_codec=%d heap_free=%u", actual_bot_id, rtc_impl->audio_codec, (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
    // 新增：extra_params 用于传递额外的AgentConfig配置参数
    if (volc_get_rtc_config(iot_info, rtc_impl->audio_codec, actual_bot_id, task_id, extra_params, &rtc_impl->info)) {
        LOGE("get rtc config failed");
        return -1;
    }
    LOGI("volc_get_rtc_config success heap_free=%u", (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
    opt = &rtc_impl->info.rtc_opt;
    return __rtc_start(rtc_impl, opt);
}

int volc_rtc_stop(volc_rtc_t handle) {
    rtc_impl_t* rtc = (rtc_impl_t *)handle;
    if (!rtc) {
        LOGE("rtc instance is NULL");
        return -1;
    }
    __rtc_stop(rtc);
    return 0;
}

int volc_rtc_send(volc_rtc_t handle, const void* data, int size, volc_data_info_t* data_info) {
    rtc_impl_t* rtc = (rtc_impl_t *)handle;
    audio_frame_info_t audio_info = {0};
    video_frame_info_t video_info = {0};
    if (NULL == rtc || NULL == data || NULL == data_info) {
        LOGE("input args is invalid, rtc(%p), data(%p), data_info(%p)", rtc, data, data_info);
        return -1;
    }
    if (rtc->p_channel_name == NULL || size <= 0) {
        LOGE("channel not ready or invalid size");
        return -1;
    }
    LOGD("volc_rtc_send type=%d size=%d heap_free=%u", data_info->type, size, (unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
    switch (data_info->type) {
        case VOLC_DATA_TYPE_AUDIO: {
            audio_info.data_type = (audio_data_type_e) data_info->info.audio.data_type;
            byte_rtc_send_audio_data(rtc->rtc, rtc->p_channel_name, data, size, &audio_info);
            break;
        }
        case VOLC_DATA_TYPE_VIDEO: {
            video_info.data_type = (video_data_type_e) data_info->info.video.data_type;
            video_info.stream_type = VIDEO_STREAM_HIGH;
            video_info.frame_type = VIDEO_FRAME_AUTO_DETECT;
            LOGD("Sending video to channel: %s, data length: %d, data type: %d", rtc->p_channel_name, size, video_info.data_type);
            byte_rtc_send_video_data(rtc->rtc, rtc->p_channel_name, data, size, &video_info);
            break;
        }
        case VOLC_DATA_TYPE_MESSAGE: {
            if (rtc->p_remote_user_id == NULL) {
                LOGW("skip message: remote user not joined");
                return -1;
            }
            LOGD("Sending message to channel: %s, remote user: %s, data length: %d, is_binary: %d",
                 rtc->p_channel_name, rtc->p_remote_user_id, size, data_info->info.message.is_binary);
            byte_rtc_rts_send_message(rtc->rtc, rtc->p_channel_name, rtc->p_remote_user_id, data, size, data_info->info.message.is_binary,
                                      RTS_MESSAGE_RELIABLE);
            break;
        }
        default:
            LOGW("unsupported data type: %d", data_info->type);
            return -1;
    }
    return 0;
}

int volc_rtc_interrupt(volc_rtc_t rtc) {
    int ret = 0;
    uint8_t* msg_ctrl = NULL;
    size_t msg_len = 0;
    rtc_impl_t* rtc_impl = (rtc_impl_t*) rtc;
    volc_data_info_t data_info = {0};
    if (!rtc_impl) {
        LOGE("rtc instance is NULL");
        return -1;
    }
    if (!rtc_impl->b_user_joined || rtc_impl->p_remote_user_id == NULL) {
        LOGW("interrupt skipped: remote user not joined");
        return -1;
    }
    if (_build_binary_message(MAGIC_CONTROL, interrupt_str, &msg_ctrl, &msg_len) != 0) {
        LOGE("build control message failed");
        return -1;
    }
    data_info.type = VOLC_DATA_TYPE_MESSAGE;
    data_info.info.message.is_binary = true;
    if ((ret = volc_rtc_send(rtc, msg_ctrl, msg_len, &data_info)) != 0) {
        LOGE("send interrupt message failed");
    }
    HAL_SAFE_FREE(msg_ctrl);
    return ret;
}

int volc_rtc_send_jpg(volc_rtc_t rtc, void* data, int size) {
    return 0;
}
