#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

#define GPIO_SIGNAL_PIN     23
#define GPIO_SIGNAL_LEVEL   1
#define GPIO_SIGNAL_INTR    ESP_INTR_FLAG_LEVEL1

// Estados da máquina de estados
typedef enum {
    WAITING_SIGNAL,
    FLASHING_FIRMWARE,
    FINISHED_FLASHING
} state_t;

// Variáveis globais
static state_t current_state = WAITING_SIGNAL;

// Função da tarefa de Espera de Sinal
void wait_signal_task(void *pvParameters) {
    while (1) {
        if (current_state == WAITING_SIGNAL) {
            // Aguarda o sinal
            printf("Aguardando sinal...\n");
            xEventGroupWaitBits(
                gpio_evt_group,
                GPIO_SIGNAL_BIT,
                pdTRUE,
                pdTRUE,
                portMAX_DELAY
            );
            printf("Sinal detectado! Iniciando gravação...\n");
            current_state = FLASHING_FIRMWARE;
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

// Função da tarefa de Gravação de Firmware
void flash_firmware_task(void *pvParameters) {
    while (1) {
        if (current_state == FLASHING_FIRMWARE) {
            // Simula a gravação do firmware
            printf("Gravando firmware...\n");
            vTaskDelay(2000 / portTICK_PERIOD_MS); // Simula o tempo de gravação
            printf("Firmware gravado com sucesso!\n");
            current_state = FINISHED_FLASHING;
        } else if (current_state == FINISHED_FLASHING) {
            printf("Gravação concluída. Voltando para a espera de sinal.\n");
            current_state = WAITING_SIGNAL; // Volta para aguardar o sinal
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

// Função para inicializar a GPIO para detecção de sinal
void init_gpio() {
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_SIGNAL_INTR;
    io_conf.pin_bit_mask = (1ULL << GPIO_SIGNAL_PIN);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
    gpio_config(&io_conf);
}

void app_main() {
    // Inicializa a GPIO
    init_gpio();

    // Cria a tarefa de Espera de Sinal
    xTaskCreate(wait_signal_task, "wait_signal_task", 2048, NULL, 10, NULL);

    // Cria a tarefa de Gravação de Firmware
    xTaskCreate(flash_firmware_task, "flash_firmware_task", 2048, NULL, 5, NULL);
}