/*********************************************************************************
* Copyright(C),2021, TUYA www.tuya.com

* FileName:		ty_user_rtsp_server.c
* Note			ty_user_rtsp_server api with debug info
* Version		V1.0.0
* Data			2021.3
*********************************************************************************/
#include <stdio.h>
#include <string.h>
#include "tuya_ring_buffer.h"
#include "tuya_ipc_media.h"
#include "rtp.h"
#include "rtsp_server.h"

#define MAX_RTSP_USER    5
// 调试打印宏，方便开关调试信息
#define RTSP_DEBUG(fmt, ...) printf("[RTSP_DEBUG] %s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
#define RTSP_ERROR(fmt, ...) printf("[RTSP_ERROR] %s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)

typedef struct {
    int active;
    IPC_STREAM_E vchn;
    IPC_STREAM_E achn;
    int got_first_frame;
    RING_BUFFER_USER_HANDLE_T v_handle;
    RING_BUFFER_USER_HANDLE_T a_handle;
} rtsp_user_info_s;

static rtsp_user_info_s users[MAX_RTSP_USER] = {0};

// 创建新的RTSP用户会话
static int rtsp_user_start()
{
    int i = 0; 
    for(i = 0; i < MAX_RTSP_USER; i++){
        if (0 == users[i].active){
            users[i].active = 1;
            users[i].vchn = E_IPC_STREAM_MAX;
            users[i].achn = E_IPC_STREAM_MAX;
            users[i].got_first_frame = 0;
            users[i].v_handle = NULL;
            users[i].a_handle = NULL;
            RTSP_DEBUG("新用户会话创建，user_id=%d", i);
            return i;
        }
    }
    RTSP_ERROR("用户会话已达上限（%d），无法创建新会话", MAX_RTSP_USER);
    return -1;
}

// 终止RTSP用户会话
static int rtsp_user_stop(int user_id)
{
    if (user_id < 0 || user_id >= MAX_RTSP_USER) {
        RTSP_ERROR("无效的user_id=%d", user_id);
        return -1;
    }
    
    if (users[user_id].active == 0) {
        RTSP_DEBUG("user_id=%d 会话已处于非活跃状态，无需关闭", user_id);
        return 0;
    }
    
    users[user_id].active = 0;
    if (users[user_id].v_handle){
        tuya_ipc_ring_buffer_close(users[user_id].v_handle);
        users[user_id].v_handle = NULL;
        RTSP_DEBUG("user_id=%d 视频环形缓冲区已关闭", user_id);
    }
    if (users[user_id].a_handle){
        tuya_ipc_ring_buffer_close(users[user_id].a_handle);
        users[user_id].a_handle = NULL;
        RTSP_DEBUG("user_id=%d 音频环形缓冲区已关闭", user_id);
    }
    
    RTSP_DEBUG("user_id=%d 会话已关闭", user_id);
    return 0;
}

// 从环形缓冲区获取音视频帧
static int rtsp_get_frame(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    if (user_id < 0 || user_id >= MAX_RTSP_USER || !users[user_id].active) {
        RTSP_ERROR("无效的user_id=%d 或会话未激活", user_id);
        return -1;
    }
    
    if (buf == NULL || plen == NULL || pts == NULL) {
        RTSP_ERROR("输入参数为NULL");
        return -1;
    }
    
    rtsp_user_info_s* puser = &users[user_id];
    RING_BUFFER_NODE_T* pnode = NULL;
    const char* media_type = (type == RTSP_MEDIA_TYPE_VIDEO) ? "视频" : "音频";

    // 初始化视频缓冲区（如果未初始化）
    if (type == RTSP_MEDIA_TYPE_VIDEO && puser->v_handle == NULL) {
        puser->v_handle = tuya_ipc_ring_buffer_open(0, 0, puser->vchn, E_RBUF_READ);
        if (puser->v_handle) {
            RTSP_DEBUG("user_id=%d 视频环形缓冲区初始化成功（通道=%d）", 
                      user_id, puser->vchn);
        } else {
            RTSP_ERROR("user_id=%d 视频环形缓冲区初始化失败（通道=%d）", 
                      user_id, puser->vchn);
        }
    }
    
    // 初始化音频缓冲区（如果未初始化）
    if (type == RTSP_MEDIA_TYPE_AUDIO && puser->a_handle == NULL) {
        puser->a_handle = tuya_ipc_ring_buffer_open(0, 0, puser->achn, E_RBUF_READ);
        if (puser->a_handle) {
            RTSP_DEBUG("user_id=%d 音频环形缓冲区初始化成功（通道=%d）", 
                      user_id, puser->achn);
        } else {
            RTSP_ERROR("user_id=%d 音频环形缓冲区初始化失败（通道=%d）", 
                      user_id, puser->achn);
        }
    }

    // 获取帧数据
    if (type == RTSP_MEDIA_TYPE_VIDEO) {
        pnode = tuya_ipc_ring_buffer_get_frame(puser->v_handle, 0);
    } else {
        pnode = tuya_ipc_ring_buffer_get_frame(puser->a_handle, 0);
    }

    if (NULL == pnode) {
        // 非错误，可能只是暂时没有数据
        // RTSP_DEBUG("user_id=%d 未获取到%s帧", user_id, media_type);
        return -1;
    }

    // 记录第一帧获取标记
    if (puser->got_first_frame == 0) {
        puser->got_first_frame = 1;
        RTSP_DEBUG("user_id=%d 成功获取第一帧%s数据", user_id, media_type);
    }

    *buf = (char *)pnode->raw_data;
    *plen = pnode->size;
    *pts = pnode->timestamp;
    
int i=0;
for(i=0;i<100;i++)
{
printf("%x \t", *(*buf+i));
}
printf("\n");
    // 每100帧打印一次统计信息（避免打印过于频繁）
    static int frame_cnt[MAX_RTSP_USER][2] = {0}; // [user_id][0:视频,1:音频]
    frame_cnt[user_id][type]++;
    if (frame_cnt[user_id][type] % 100 == 0) {
        RTSP_DEBUG("user_id=%d %s帧统计：已发送%d帧，当前帧大小=%d字节，时间戳=%llu",
                  user_id, media_type, frame_cnt[user_id][type], *plen, *pts);
    }
    
    return 0;
}

// 获取主码流音视频帧
static int rtsp_get_frame_main(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    // 设置主码流通道
    users[user_id].vchn = E_IPC_STREAM_VIDEO_MAIN;
    users[user_id].achn = E_IPC_STREAM_AUDIO_MAIN;
    RTSP_DEBUG("user_id=%d 使用主码流（视频通道=%d，音频通道=%d）",
              user_id, users[user_id].vchn, users[user_id].achn);
    
    return rtsp_get_frame(user_id, type, buf, plen, pts);
}

// 获取子码流音视频帧
static int rtsp_get_frame_sub(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    // 设置子码流通道
    users[user_id].vchn = E_IPC_STREAM_VIDEO_SUB;
    users[user_id].achn = E_IPC_STREAM_AUDIO_MAIN;
    RTSP_DEBUG("user_id=%d 使用子码流（视频通道=%d，音频通道=%d）",
              user_id, users[user_id].vchn, users[user_id].achn);
    
    return rtsp_get_frame(user_id, type, buf, plen, pts);
}

// 获取主码流编码格式
static RTP_CODEC_E get_main_codec(RTSP_MEDIA_TYPE_E type)
{
    switch (type) {
    case RTSP_MEDIA_TYPE_VIDEO: return RTP_CODEC_H265;
    case RTSP_MEDIA_TYPE_AUDIO: return 0; // 先禁用音频
    default: return 0;
    }
}

// 获取子码流编码格式
static RTP_CODEC_E get_sub_codec(RTSP_MEDIA_TYPE_E type)
{
    switch (type) {
    case RTSP_MEDIA_TYPE_VIDEO: return RTP_CODEC_H265;
    case RTSP_MEDIA_TYPE_AUDIO: return 0; // 先禁用音频
    default: return 0;
    }
}

// 获取采样率（时钟频率）
static int get_sample_rate(RTSP_MEDIA_TYPE_E type)
{
    int rate;
    switch (type){
    case RTSP_MEDIA_TYPE_VIDEO:
        rate = 90000; // RTSP视频标准时钟频率
        RTSP_DEBUG("视频采样率：%d Hz", rate);
        break;
    case RTSP_MEDIA_TYPE_AUDIO:
        rate = 8000;  // PCM音频采样率
        RTSP_DEBUG("音频采样率：%d Hz", rate);
        break;
    default:
        rate = 8000;
        RTSP_ERROR("未知媒体类型（%d），使用默认采样率%d Hz", type, rate);
        break;
    }
    return rate;
}

// 获取主码流名称
static int rtsp_get_name_main(char* buf, int* buf_len)
{
    if (buf == NULL) {
        RTSP_ERROR("输入缓冲区为NULL");
        return -1;
    }

    const char* name = "stream0";
    strncpy(buf, name, strlen(name));
    if (buf_len != NULL) {
        *buf_len = strlen(name);
    }
    RTSP_DEBUG("主码流名称：%s（长度=%d）", name, strlen(name));
    return 0;
}

// 获取子码流名称
static int rtsp_get_name_sub(char* buf, int* buf_len)
{
    if (buf == NULL) {
        RTSP_ERROR("输入缓冲区为NULL");
        return -1;
    }

    const char* name = "stream1";
    strncpy(buf, name, strlen(name));
    if (buf_len != NULL) {
        *buf_len = strlen(name);
    }
    RTSP_DEBUG("子码流名称：%s（长度=%d）", name, strlen(name));
    return 0;
}

// 启动RTSP服务器
int ty_user_rtsp_server_start(char *pwd)
{
    RTSP_STREAM_SRC_T src[2] = {{0}};
    
    // 配置主码流源
    src[0].get_codec = get_main_codec;
    src[0].get_frame = rtsp_get_frame_main;
    src[0].get_sample_rate = get_sample_rate;
    src[0].start = rtsp_user_start;
    src[0].stop = rtsp_user_stop;
    src[0].get_name = rtsp_get_name_main;

    // 配置子码流源
    src[1].get_codec = get_sub_codec;
    src[1].get_frame = rtsp_get_frame_sub;
    src[1].get_sample_rate = get_sample_rate;
    src[1].start = rtsp_user_start;
    src[1].stop = rtsp_user_stop;
    src[1].get_name = rtsp_get_name_sub;

    // 启动RTSP服务器（用户名admin，指定密码，端口8554）
    RTSP_DEBUG("启动RTSP服务器，用户名=空，密码=%s，端口=8554", pwd ? pwd : "空");
     tuya_ipc_rtsp_server_start(NULL, NULL, 8554);
    //tuya_ipc_rtsp_server_start(NULL, NULL, 8554);
    
    // 注册码流源
    tuya_ipc_rtsp_server_register_stream_src(src);
    RTSP_DEBUG("主码流（stream0）已注册");
    
    tuya_ipc_rtsp_server_register_stream_src(src + 1);
    RTSP_DEBUG("子码流（stream1）已注册");
    
    RTSP_DEBUG("RTSP服务器启动完成");
    return 0;
}

// 停止RTSP服务器
int ty_user_rtsp_server_stop()
{
    RTSP_DEBUG("开始停止RTSP服务器");
    tuya_ipc_rtsp_server_stop();
    RTSP_DEBUG("RTSP服务器已停止");
    return 0;
}

// 设置RTSP服务器密码
int ty_user_rtsp_set_pwd(char *pwd)
{
    if (pwd == NULL) {
        RTSP_ERROR("密码为空，设置失败");
        return -1;
    }
    
    int ret = tuya_ipc_rtsp_server_set_password(pwd);
    if (ret != 0) {
        RTSP_ERROR("密码设置失败（返回值=%d）", ret);
        return -1;
    }
    
    RTSP_DEBUG("RTSP服务器密码设置成功");
    return 0;
}