/**
 * @file agent_protocol.c
 * @brief 文本协议解析（按前缀长度优先匹配）
 */

#include "protocol/agent_protocol.h"
#include <string.h>

/**
 * @brief 判断字符串是否以指定前缀开头
 */
static bool starts_with(const char *str, size_t str_len, const char *prefix)
{
    size_t plen = strlen(prefix);
    if (str_len < plen) {
        return false;
    }
    return strncmp(str, prefix, plen) == 0;
}

/**
 * @brief 按前缀匹配消息类型（长前缀优先）
 *
 * @param buf  消息缓冲区（不要求 null 终止）
 * @param len  消息长度
 */
static agent_msg_type_t protocol_get_type(const char *buf, size_t len)
{
    if (!buf || len == 0) {
        return AGENT_MSG_TYPE_UNKNOWN;
    }

    /* ====== TTS Events (longest "[E]:[TTS_" prefixes) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_TTS_BEGIN_AUDIO)) {
        return AGENT_MSG_TYPE_TTS_BEGIN_AUDIO;
    }
    if (starts_with(buf, len, AGENT_PREFIX_TTS_END_AUDIO)) {
        return AGENT_MSG_TYPE_TTS_END_AUDIO;
    }
    if (starts_with(buf, len, AGENT_PREFIX_TTS_BEGIN)) {
        return AGENT_MSG_TYPE_TTS_BEGIN;
    }
    if (starts_with(buf, len, AGENT_PREFIX_TTS_END)) {
        return AGENT_MSG_TYPE_TTS_END;
    }

    /* ====== License (before generic [E]:) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_LICENSE)) {
        return AGENT_MSG_TYPE_LICENSE;
    }

    /* ====== Specific Event Messages (before generic [E]:) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_MEDIA_GEN_RESULT)) {
        return AGENT_MSG_TYPE_MEDIA_GEN_RESULT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_MEDIA_GEN_START)) {
        return AGENT_MSG_TYPE_MEDIA_GEN_RESULT; /* treat start same as result for now */
    }
    if (starts_with(buf, len, AGENT_PREFIX_REMOTE_PLAYER_BEGIN)) {
        return AGENT_MSG_TYPE_REMOTE_PLAYER_BEGIN;
    }
    if (starts_with(buf, len, AGENT_PREFIX_REMOTE_PLAYER_END)) {
        return AGENT_MSG_TYPE_REMOTE_PLAYER_END;
    }
    if (starts_with(buf, len, AGENT_PREFIX_VOICE_INTERRUPT)) {
        return AGENT_MSG_TYPE_INTERRUPT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_VOICE_COMING)) {
        return AGENT_MSG_TYPE_VOICE_COMING;
    }
    if (starts_with(buf, len, AGENT_PREFIX_VOICE_DISAPPEAR)) {
        return AGENT_MSG_TYPE_VOICE_DISAPPEAR;
    }
    if (starts_with(buf, len, AGENT_PREFIX_INTERRUPT)) {
        return AGENT_MSG_TYPE_INTERRUPT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_UPLOAD_IMAGE)) {
        return AGENT_MSG_TYPE_UPLOAD_IMAGE;
    }
    if (starts_with(buf, len, AGENT_PREFIX_PLAY_AUDIO)) {
        return AGENT_MSG_TYPE_PLAY_AUDIO;
    }
    if (starts_with(buf, len, AGENT_PREFIX_CONID)) {
        return AGENT_MSG_TYPE_CONID;
    }
    if (starts_with(buf, len, AGENT_PREFIX_AGENTID)) {
        return AGENT_MSG_TYPE_AGENTID;
    }
    if (starts_with(buf, len, AGENT_PREFIX_LEAVING)) {
        return AGENT_MSG_TYPE_LEAVING;
    }
    if (starts_with(buf, len, AGENT_PREFIX_TAG_MSG)) {
        return AGENT_MSG_TYPE_TAG_MSG;
    }
    if (starts_with(buf, len, AGENT_PREFIX_DIRECT_PLAY)) {
        return AGENT_MSG_TYPE_DIRECT_PLAY;
    }

    /* ====== ASR Messages (longest "[Q]:" variants first) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_ASR_MID_CONT)) {
        return AGENT_MSG_TYPE_ASR_MID_CONT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_ASR_MID)) {
        return AGENT_MSG_TYPE_ASR_MID;
    }
    if (starts_with(buf, len, AGENT_PREFIX_ASR_CONT)) {
        return AGENT_MSG_TYPE_ASR_CONT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_ASR)) {
        return AGENT_MSG_TYPE_ASR;
    }

    /* ====== AI/LLM Messages (longest "[A]:" variants first) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_AI_HINT)) {
        return AGENT_MSG_TYPE_AI_HINT;
    }
    if (starts_with(buf, len, AGENT_PREFIX_AI_MID)) {
        return AGENT_MSG_TYPE_AI_MID;
    }
    if (starts_with(buf, len, AGENT_PREFIX_AI)) {
        return AGENT_MSG_TYPE_AI;
    }

    /* ====== Generic [E]: Event (catch-all after specific events) ====== */
    if (starts_with(buf, len, AGENT_PREFIX_EVENT)) {
        return AGENT_MSG_TYPE_EVENT;
    }

    /* ====== Function Call ====== */
    if (starts_with(buf, len, AGENT_PREFIX_FUNCTION)) {
        return AGENT_MSG_TYPE_FUNCTION;
    }

    /* ====== Done ====== */
    if (starts_with(buf, len, AGENT_PREFIX_DONE)) {
        return AGENT_MSG_TYPE_DONE;
    }

    return AGENT_MSG_TYPE_UNKNOWN;
}

/**
 * @brief 快速获取消息类型（要求 null 终止的字符串）
 */
agent_msg_type_t agent_protocol_get_type(const char *buf)
{
    if (!buf) {
        return AGENT_MSG_TYPE_UNKNOWN;
    }
    return protocol_get_type(buf, strlen(buf));
}

/**
 * 前缀字符串表，按消息类型索引（用于计算内容偏移）
 */
static const char *get_prefix_for_type(agent_msg_type_t type)
{
    switch (type) {
    case AGENT_MSG_TYPE_ASR:               return AGENT_PREFIX_ASR;
    case AGENT_MSG_TYPE_ASR_MID:           return AGENT_PREFIX_ASR_MID;
    case AGENT_MSG_TYPE_ASR_CONT:          return AGENT_PREFIX_ASR_CONT;
    case AGENT_MSG_TYPE_ASR_MID_CONT:      return AGENT_PREFIX_ASR_MID_CONT;
    case AGENT_MSG_TYPE_AI:                return AGENT_PREFIX_AI;
    case AGENT_MSG_TYPE_AI_MID:            return AGENT_PREFIX_AI_MID;
    case AGENT_MSG_TYPE_AI_HINT:           return AGENT_PREFIX_AI_HINT;
    case AGENT_MSG_TYPE_TTS_BEGIN:         return AGENT_PREFIX_TTS_BEGIN;
    case AGENT_MSG_TYPE_TTS_END:           return AGENT_PREFIX_TTS_END;
    case AGENT_MSG_TYPE_TTS_BEGIN_AUDIO:   return AGENT_PREFIX_TTS_BEGIN_AUDIO;
    case AGENT_MSG_TYPE_TTS_END_AUDIO:     return AGENT_PREFIX_TTS_END_AUDIO;
    case AGENT_MSG_TYPE_LICENSE:           return AGENT_PREFIX_LICENSE;
    case AGENT_MSG_TYPE_VOICE_COMING:      return AGENT_PREFIX_VOICE_COMING;
    case AGENT_MSG_TYPE_VOICE_DISAPPEAR:   return AGENT_PREFIX_VOICE_DISAPPEAR;
    case AGENT_MSG_TYPE_INTERRUPT:         return AGENT_PREFIX_INTERRUPT;
    case AGENT_MSG_TYPE_UPLOAD_IMAGE:      return AGENT_PREFIX_UPLOAD_IMAGE;
    case AGENT_MSG_TYPE_PLAY_AUDIO:        return AGENT_PREFIX_PLAY_AUDIO;
    case AGENT_MSG_TYPE_CONID:             return AGENT_PREFIX_CONID;
    case AGENT_MSG_TYPE_AGENTID:           return AGENT_PREFIX_AGENTID;
    case AGENT_MSG_TYPE_LEAVING:           return AGENT_PREFIX_LEAVING;
    case AGENT_MSG_TYPE_TAG_MSG:           return AGENT_PREFIX_TAG_MSG;
    case AGENT_MSG_TYPE_MEDIA_GEN_RESULT:  return AGENT_PREFIX_MEDIA_GEN_RESULT;
    case AGENT_MSG_TYPE_REMOTE_PLAYER_BEGIN: return AGENT_PREFIX_REMOTE_PLAYER_BEGIN;
    case AGENT_MSG_TYPE_REMOTE_PLAYER_END: return AGENT_PREFIX_REMOTE_PLAYER_END;
    case AGENT_MSG_TYPE_DIRECT_PLAY:       return AGENT_PREFIX_DIRECT_PLAY;
    case AGENT_MSG_TYPE_EVENT:             return AGENT_PREFIX_EVENT;
    case AGENT_MSG_TYPE_FUNCTION:          return AGENT_PREFIX_FUNCTION;
    case AGENT_MSG_TYPE_DONE:              return AGENT_PREFIX_DONE;
    default:                               return "";
    }
}

int agent_protocol_parse_text(const char *buf, size_t len, agent_protocol_result_t *result)
{
    if (!buf || len == 0 || !result) {
        return -1;
    }

    memset(result, 0, sizeof(*result));

    result->type = protocol_get_type(buf, len);

    if (result->type == AGENT_MSG_TYPE_UNKNOWN) {
        result->content = buf;
        result->content_len = len;
        result->is_final = false;
        return -2;
    }

    /* 按前缀长度计算内容偏移 */
    const char *prefix = get_prefix_for_type(result->type);
    size_t prefix_len = strlen(prefix);

    if (prefix_len <= len) {
        result->content = buf + prefix_len;
        result->content_len = len - prefix_len;
    } else {
        result->content = buf + len;
        result->content_len = 0;
    }

    /* 判断是否为最终结果 */
    switch (result->type) {
    case AGENT_MSG_TYPE_ASR_MID:
    case AGENT_MSG_TYPE_ASR_MID_CONT:
    case AGENT_MSG_TYPE_AI_MID:
        result->is_final = false;
        break;
    default:
        result->is_final = true;
        break;
    }

    return 0;
}
