#ifndef UAV_PAIRING_H
#define UAV_PAIRING_H

#include <cstdint>
#include <cstddef>

// ============================================================================
// uav_pairing.h — PAIR_REQ / PAIR_RSP frame handling for uav_relay.cpp
//
// Real gap found and fixed here: uav_relay_init(hmac_key, hmac_key_len)
// only ever stored whatever key the CALLER passed in (or none) -- nothing
// in the actual firmware boot path called it with a real key, so
// s_hmac_key_len stayed 0 forever and verify_hmac() rejected every real
// command. There was no wireless pairing mechanism at all, on either side
// of this handshake (drone-companion/SPEC.md documented one, but its own
// implementation was also missing the PAIR_REQ receive handler -- fixed
// there too, see drone-companion/src/pairing.{h,cpp}).
//
// This mirrors drone-companion's storage.h/pairing.h design (same wire
// protocol, same PairingData-equivalent fields, same 128-byte PAIR_REQ /
// 16-byte PAIR_RSP layout) but uses THIS repo's existing raw ESP-IDF NVS
// pattern (nvs_open/nvs_get_blob/nvs_set_blob, see auth_gate.cpp) instead
// of drone-companion's Arduino Preferences wrapper -- both are real
// encrypted-at-rest NVS storage, just different library conventions
// already established in each codebase.
//
// msg_type: PDL_MSG_TYPE_UAV_PAIR_REQ/RSP moved to 0x1E/0x1F (see
// uav_relay.h) -- the SPEC.md-documented 0x0D/0x0E collide with
// mesh_routing.h's MSG_TYPE_MESH_ROUTE/MSG_TYPE_MESH_ACK, which is
// compiled into the same env:heltec_wifi_lora_v4_uav_bridge build variant.
//
// SCOPE (explicitly not implemented, matching drone-companion/pairing.h's
// own flagged gap): SPEC.md 7.1's admin-token-authenticated re-pair path
// needs a factory-provisioned secret this repo has no existing
// provisioning flow for. Only cold-boot-with-empty-root and BOOT-button
// hold are wired.
// ============================================================================

#define UAV_PAIR_REQ_FRAME_SIZE   128
#define UAV_PAIR_RSP_FRAME_SIZE    16
#define UAV_PAIR_BTN_HOLD_MS     5000u
#define UAV_PAIR_WINDOW_MS      60000u

enum class UavDroneProfile : uint8_t {
    ARDUPILOT_COPTER = 0,
    ARDUPILOT_PLANE  = 1,
    PX4              = 2,
    BETAFLIGHT       = 3,
    UNKNOWN          = 0xFF,
};

enum class UavPairRspStatus : uint8_t {
    OK                 = 0,
    PAIR_MODE_REQUIRED = 4,
    STORAGE_FAILURE    = 5,
};

struct UavPairingData {
    uint8_t  hmac_root[32];
    uint8_t  operator_cert_hash[8];
    char     drone_id[24];
    char     operator_callsign[24];
    uint8_t  policy_manifest_hash[32];
    bool     allow_terminate;
    UavDroneProfile profile;
};

struct UavPairResponseFrame {
    uint8_t vehicle_hash[8];
    uint8_t fw_major;
    uint8_t fw_minor;
    uint8_t fw_patch;
    UavPairRspStatus status;
};

// ── Pure frame parse/build (no NVS, no radio -- directly unit-testable) ──

bool uav_pairing_parse_request(const uint8_t* data, size_t len, UavPairingData& out);
size_t uav_pairing_build_response(const UavPairResponseFrame& r, uint8_t* out, size_t out_len);

// ── State machine + NVS-backed storage ──

// Load any persisted HMAC root from NVS into the in-RAM mirror, and open
// the pairing window if none is persisted yet (SPEC.md 7.1 cold-boot
// path). Call once at boot, before uav_relay_init() needs the key.
void uav_pairing_init(uint32_t now_ms);

// Drives the pair-window deadline and the BOOT-button-hold trigger.
// button_held_ms is sampled by the caller (main.cpp), same
// hardware-independence split as drone-companion/pairing.h.
void uav_pairing_tick(uint32_t now_ms, uint32_t button_held_ms);

bool uav_pairing_is_paired();
bool uav_pairing_get_hmac_root(uint8_t out[32]);
bool uav_pairing_window_open();

// Full request handler: parse -> check window -> persist to NVS -> build
// response. Returns false (nothing to send) only if the frame doesn't
// parse as a well-formed PAIR_REQ at all -- matches this codebase's
// established "malformed/corrupt is indistinguishable from noise, drop
// silently" discipline (command_handler.cpp, mesh_routing.cpp).
bool uav_pairing_process_request(const uint8_t* data, size_t len, uint32_t now_ms,
                                 const uint8_t vehicle_hash[8],
                                 uint8_t out_response[UAV_PAIR_RSP_FRAME_SIZE],
                                 size_t* out_response_len);

#ifdef UNIT_TEST
void uav_pairing_test_reset();
#endif

#endif // UAV_PAIRING_H
