#include "tianwen.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "driver/gpio.h"  // 确保包含此头文件（定义了ESP_INTR_FLAG_DEFAULT）
#define TAG "Application"

// 静态成员初始化
QueueHandle_t Gpio5InterruptHandler::s_gpio_evt_queue = nullptr;

// 构造函数
Gpio5InterruptHandler::Gpio5InterruptHandler() 
    : m_gpio_num(GPIO_NUM_5), m_task_handle(nullptr) {
    // 初始化成员变量
}

// 析构函数：清理资源
Gpio5InterruptHandler::~Gpio5InterruptHandler() {
    // 删除任务（如果存在）
    if (m_task_handle != nullptr) {
        vTaskDelete(m_task_handle);
        m_task_handle = nullptr;
    }

    // 删除队列（如果存在）
    if (s_gpio_evt_queue != nullptr) {
        vQueueDelete(s_gpio_evt_queue);
        s_gpio_evt_queue = nullptr;
    }

    // 移除中断处理函数并卸载中断服务
    gpio_isr_handler_remove(m_gpio_num);
    gpio_uninstall_isr_service();
}

// 中断服务程序（ISR）：将事件放入队列
void IRAM_ATTR Gpio5InterruptHandler::isr_handler(void* arg) {
    uint32_t gpio_num = (uint32_t)arg;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // 向队列发送中断事件
    xQueueSendFromISR(s_gpio_evt_queue, &gpio_num, &xHigherPriorityTaskWoken);
    // 如果需要，触发任务切换
    if (xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR();
    }
}

// 任务包装函数：转发到成员函数
void Gpio5InterruptHandler::task_wrapper(void* arg) {
    // 将void*转换为类实例指针，调用成员函数
    static_cast<Gpio5InterruptHandler*>(arg)->task_handler();
}

// 实际的任务处理逻辑：从队列接收事件并处理
void Gpio5InterruptHandler::task_handler() {
    uint32_t io_num;
    for (;;) { // 无限循环，等待中断事件
        if (xQueueReceive(s_gpio_evt_queue, &io_num, portMAX_DELAY)) {
            // 打印中断信息和当前电平
            ESP_LOGI(TAG, "GPIO[%u] interrupt, value: %d",
                     (unsigned int)io_num,
                     gpio_get_level((gpio_num_t)io_num));
        }
    }
}

// 初始化函数：配置GPIO和中断
esp_err_t Gpio5InterruptHandler::init() {
    // 配置GPIO参数
    gpio_config_t io_conf = {};
    io_conf.intr_type = GPIO_INTR_POSEDGE;       // 上升沿触发
    io_conf.mode = GPIO_MODE_INPUT;              // 输入模式
    io_conf.pin_bit_mask = (1ULL << m_gpio_num); // 引脚掩码（仅GPIO5）
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;     // 启用上拉电阻
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;// 禁用下拉电阻

    // 应用GPIO配置
    esp_err_t ret = gpio_config(&io_conf);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "GPIO configuration failed: %s", esp_err_to_name(ret));
        return ret;
    }

    // 创建中断事件队列（容量10，每个元素为uint32_t）
    s_gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    if (s_gpio_evt_queue == nullptr) {
        ESP_LOGE(TAG, "Failed to create GPIO event queue");
        return ESP_FAIL;
    }

    // 创建中断处理任务
    ret = xTaskCreate(
        task_wrapper,          // 任务函数（静态包装函数）
        "gpio5_intr_task",     // 任务名称
        2048,                  // 任务栈大小
        this,                  // 传递给任务的参数（类实例指针）
        10,                    // 任务优先级
        &m_task_handle         // 任务句柄输出
    );
    if (ret != pdPASS) {
        ESP_LOGE(TAG, "Failed to create interrupt task");
        vQueueDelete(s_gpio_evt_queue); // 回滚：删除已创建的队列
        s_gpio_evt_queue = nullptr;
        return ESP_FAIL;
    }

    // 安装GPIO中断服务
    ret = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to install ISR service: %s", esp_err_to_name(ret));
        return ret;
    }

    // 为GPIO5注册中断处理函数
    ret = gpio_isr_handler_add(m_gpio_num, isr_handler, (void*)m_gpio_num);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to add ISR handler: %s", esp_err_to_name(ret));
        return ret;
    }

    ESP_LOGI(TAG, "GPIO5 rising edge interrupt initialized successfully");
    return ESP_OK;
}