#ifndef OTA_FIRMWARE_H
#define OTA_FIRMWARE_H

// ============================================================================
// ota_firmware.h — Over-the-air FIRMWARE updates (ArduinoOTA / espota)
//
// NOT THE SAME THING AS ota_adapter.h. That module delivers TFLite MODEL files
// in 512 KB PSRAM slots over LoRa, signed with Ed25519. This module replaces
// the running FIRMWARE IMAGE over WiFi. They share a prefix and nothing else.
//
// WHY IT DIDN'T EXIST BEFORE
// --------------------------
// The original partitions.csv had a single app slot, so firmware OTA was
// structurally impossible regardless of code — ESP-IDF stages an incoming
// image in the inactive slot and flips otadata on reboot, and there was no
// inactive slot. partitions_8mb_ota.csv / partitions_16mb_ota.csv add app1,
// which is what makes this module meaningful.
//
// USAGE
// -----
// Once a unit is on WiFi it announces itself over mDNS as SENSOR_NAME. Flash
// it from anywhere on the same LAN:
//
//     pio run -e <env> -t upload --upload-port <ip-or-hostname>
//
// with `upload_protocol = espota` set for that env (or passed on the command
// line). No cable, no port juggling, no walking to the sensor.
//
// FIRST FLASH IS STILL WIRED
// --------------------------
// Installing the dual-app partition table requires a full erase, which only
// USB can do. Every unit needs exactly one more cable session; everything
// after that is wireless. That is a property of ESP32 partitioning, not a
// limitation of this module.
//
// BOARD SCOPE
// -----------
// ESP32-family only (Heltec V3/V4, LilyGo T-Deck, RAK's ESP32-based WisBlock
// cores such as RAK11200). A RAK4631 is nRF52840 and a RAK3172 is STM32WL —
// neither runs ESP-IDF, so neither can use this path. Those need their own
// DFU mechanism.
//
// SECURITY NOTE (deliberate, flagged rather than hidden)
// -----------------------------------------------------
// No OTA password is set by default, matching the existing unauthenticated
// wifi_status_server on port 80. Anyone on the same LAN who can reach the
// device can push firmware to it. That is acceptable for a trusted home/lab
// LAN and is the same trust model the rest of this firmware already assumes,
// but it is NOT acceptable for a deployed field unit on an untrusted network.
// ota_firmware_set_password() exists so a password can be applied without
// baking a secret into the repository.
// ============================================================================

// Start the OTA responder. Safe to call repeatedly — internally no-ops if
// already started or if WiFi is not connected yet. Call from the main loop
// alongside the other WiFi ticks.
void ota_firmware_tick();

// Set an OTA password at runtime (persisted to NVS). Pass nullptr or "" to
// clear it. Exposed via the OTA_PASSWORD serial command so no credential is
// ever committed to source.
void ota_firmware_set_password(const char* password);

// True once the OTA responder is listening.
bool ota_firmware_is_active();

// Running image slot ("app0"/"app1") and whether a rollback is pending, for
// REPORT_STATUS. After a wireless update this is how you confirm the unit
// actually booted the new image rather than falling back.
const char* ota_firmware_running_partition();

#endif // OTA_FIRMWARE_H
