#include <Arduino.h>
#include "efuse.h"
#include <soc/efuse_reg.h>
#include <esp_efuse.h>
#include <esp_efuse_table.h>
#include "parameters.h"

static const struct {
    const esp_efuse_desc_t **desc;
    const char *name;
} fuses[] = {
    { ESP_EFUSE_DIS_DOWNLOAD_MODE, "DIS_DOWNLOAD_MODE" },
    { ESP_EFUSE_DIS_USB_JTAG, "DIS_USB_JTAG" },
#ifdef ESP_EFUSE_DIS_PAD_JTAG
    { ESP_EFUSE_DIS_PAD_JTAG, "DIS_PAD_JTAG" },
#endif
#ifdef ESP_EFUSE_DIS_USB_SERIAL_JTAG
    { ESP_EFUSE_DIS_USB_SERIAL_JTAG, "DIS_USB_SERIAL_JTAG" },
#endif
#ifdef ESP_EFUSE_DIS_USB_DOWNLOAD_MODE
    { ESP_EFUSE_DIS_USB_DOWNLOAD_MODE, "DIS_USB_DOWNLOAD_MODE" },
#endif
#ifdef ESP_EFUSE_DIS_FORCE_DOWNLOAD
    { ESP_EFUSE_DIS_FORCE_DOWNLOAD, "DIS_FORCE_DOWNLOAD" },
#endif
#ifdef ESP_EFUSE_DIS_LEGACY_SPI_BOOT
    { ESP_EFUSE_DIS_LEGACY_SPI_BOOT, "DIS_LEGACY_SPI_BOOT" },
#endif
};

/*
  set efuses to prevent firmware upload except via signed web
  interface
  当模块被设置为最高级别锁定（lock_level≥2）时，检查并永久熔断 ESP32 的关键 eFuse 位
  （如禁用 JTAG、禁用固件烧录、禁用 NVS 擦除等），实现硬件级防篡改，且熔断后无法恢复。
 */
void set_efuses(void)
{
    bool some_unset = false;
    for (const auto &f : fuses) {
        const bool v = esp_efuse_read_field_bit(f.desc); // 读取单个eFuse位的值

        Serial.printf("%s = %u\n", f.name, unsigned(v));  // 打印当前状态（0=未熔断，1=已熔断）
        some_unset |= !v; // 只要有一个eFuse位未熔断，some_unset=true
    }
    if (g.lock_level >= 2 && some_unset) { // 仅当：1.锁定级别≥2（最高级锁定）；2.有未熔断的熔丝 → 执行熔断
        Serial.printf("Burning efuses\n"); 
        esp_efuse_batch_write_begin();
        for (const auto &f : fuses) {
            const bool v = esp_efuse_read_field_bit(f.desc); // 启动eFuse批量写入（ESP32要求批量操作）
            if (!v) {
                Serial.printf("%s -> 1\n", f.name);
                auto ret = esp_efuse_write_field_bit(f.desc); // 熔断该位（写入1）
                if (ret != ESP_OK) {
                    Serial.printf("%s change failed\n", f.name); // 打印熔断失败日志
                }
            }
        }
        esp_efuse_batch_write_commit(); // 提交批量写入（真正执行熔断）
    }
}

