#include "uart_component.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include <string.h>
#include <stdio.h>

// T07: UART TX 全局互斥锁
// 保护所有 uart_write_bytes 调用，防止 face_tracker 任务与 application 任务并发
// 写入造成帧交织（RESEARCH A3）
static SemaphoreHandle_t s_uart_tx_mutex = nullptr;

// 初始化 ESP32 → RP2040 的 UART 通信
// 波特率 115200，8 数据位，无校验，1 停止位，无流控
void uart_init_component() {
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
    };
    uart_param_config(UART_PORT_NUM, &uart_config);
    // GPIO17=TX（发送到 RP2040 的 GP5/RX），GPIO18=RX（接收 RP2040 的 GP4/TX）
    uart_set_pin(UART_PORT_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_driver_install(UART_PORT_NUM, BUF_SIZE, 0, 0, NULL, 0);

    // T07: 创建 TX 全局互斥锁
    if (s_uart_tx_mutex == nullptr) {
        s_uart_tx_mutex = xSemaphoreCreateMutex();
    }
}

// 发送状态字符串给 RP2040，末尾自动添加 \r\n
// RP2040 的 main.py 通过 coms.esp_read() 按 \n 分割解析
// 支持的状态字符串：idle / listening / speaking / thinking / neutral / happy 等
// T07: 加锁，防与 uart_send_face 并发撕包
void uart_send_string(const char* str) {
    if (s_uart_tx_mutex != nullptr) {
        xSemaphoreTake(s_uart_tx_mutex, portMAX_DELAY);
    }
    uart_write_bytes(UART_PORT_NUM, str, strlen(str));
    uart_write_bytes(UART_PORT_NUM, "\r\n", 2);
    if (s_uart_tx_mutex != nullptr) {
        xSemaphoreGive(s_uart_tx_mutex);
    }
}

// 发送说话开始信号（预留接口，RP2040 当前未使用）
// 注意：经由 uart_send_string 间接加锁
void uart_signal_start() {
    uart_send_string("[SPEAK_START]\n");
}

// 发送说话停止信号（预留接口，RP2040 当前未使用）
// 注意：经由 uart_send_string 间接加锁
void uart_signal_stop() {
    uart_send_string("[SPEAK_STOP]\n");
}

// T07: 发送人脸检测坐标到 RP2040
// 格式："face:<x>,<y>\r\n"，x/y ∈ [-112, +112]（RP2040 pixel_centre=112）
// 由 face_tracker 任务以 Kconfig FPS 频率调用（默认 10 FPS）
// 必须是 C 链接（extern "C"）——face_tracker.cc 用 weak 符号前置声明，
// 链接时本 strong 实现自动覆盖 weak。
extern "C" void uart_send_face(int x_offset, int y_offset) {
    if (s_uart_tx_mutex == nullptr) return;  // UART 未初始化，直接丢弃
    char buf[24];
    int n = snprintf(buf, sizeof(buf), "face:%d,%d", x_offset, y_offset);
    if (n <= 0 || n >= (int)sizeof(buf)) return;  // 格式化失败/截断
    xSemaphoreTake(s_uart_tx_mutex, portMAX_DELAY);
    uart_write_bytes(UART_PORT_NUM, buf, n);
    uart_write_bytes(UART_PORT_NUM, "\r\n", 2);
    xSemaphoreGive(s_uart_tx_mutex);
}
