#ifndef WIFI_ODID_SCANNER_H
#define WIFI_ODID_SCANNER_H

// ============================================================================
// wifi_odid_scanner.h — WiFi Beacon ASTM F3411 OpenDroneID scanner for T1
//
// Ported from PDL Witness's pdl_witness.c (classify_oui / find_droneid_vendor_ie
// / parse_droneid_location) — the WiFi-side counterpart to ble_odid_scanner.
// Reuses ble_odid_scanner.h's OdidLocation / odid_decode_location /
// odid_extract_basic_id_serial for the actual ASTM F3411 message-body decode
// (that logic is transport-independent once you have the raw message bytes;
// only *finding* those bytes differs between BLE adverts and WiFi beacons).
//
// Many consumer drones (DJI, Autel, Skydio, Parrot) broadcast Remote ID as a
// vendor-specific information element (802.11 tag 0xDD) inside their own
// WiFi beacon frames, using a manufacturer OUI. This module classifies that
// OUI and, when present, decodes the ODID message(s) carried in the IE.
//
// Unlike ble_odid_scanner (which needs its own NimBLE scan role), this hooks
// into WiFi promiscuous mode that T1 already runs for RF spectrum capture —
// no new radio mode required. ESP-IDF only allows ONE registered
// esp_wifi_set_promiscuous_rx_cb, so wifi_odid_scanner_process_packet() must
// be called from inside whichever callback is already registered
// (see main.cpp's combined_promiscuous_cb), not registered independently.
// ============================================================================

#include <cstdint>
#include <cstddef>
#include "ble_odid_scanner.h"  // OdidVendorClass, OdidLocation, shared decode fns

// Result of parsing one 802.11 beacon frame.
struct WifiOdidParseResult {
    bool         hit;          // true if a known drone vendor IE was found
    uint8_t      vendor;       // OdidVendorClass
    bool         has_serial;
    char         serial[21];
    OdidLocation location;
};

// ---------------------------------------------------------------------------
// Pure parsing — no ESP-IDF dependency, safe to call from native tests.
// ---------------------------------------------------------------------------

// Classify a beacon frame's vendor-specific IE (802.11 tag 0xDD) against
// known drone manufacturer OUIs. frame[0] must be the 802.11 Frame Control
// low byte (0x80 = Beacon; anything else returns ODID_VENDOR_UNKNOWN).
uint8_t wifi_odid_classify_oui(const uint8_t* frame, size_t frame_len);

// Full parse: classify + locate the vendor IE + decode whichever ASTM F3411
// message(s) (Basic ID / Location) are present in it.
WifiOdidParseResult wifi_odid_parse_beacon(const uint8_t* frame, size_t frame_len);

// ---------------------------------------------------------------------------
// ESP32/Arduino integration (real hardware only).
// ---------------------------------------------------------------------------
#ifdef ARDUINO

// Process one promiscuous-mode WiFi packet (buf is the raw
// wifi_promiscuous_pkt_t* the ESP-IDF driver hands to the rx callback).
// Call this from inside main.cpp's combined_promiscuous_cb.
void wifi_odid_scanner_process_packet(void* buf);

struct WifiOdidScannerStats {
    uint32_t frames_seen;
    uint32_t rid_hits;
    uint32_t location_hits;
    uint32_t blue_force_matches;
};

// Snapshot module stats. out must be non-null.
void wifi_odid_scanner_get_stats(WifiOdidScannerStats* out);

// Test-only injection: feeds a synthetic 802.11 beacon frame through the
// exact same classify -> decode -> blue-force -> FFPS pipeline a real
// captured beacon would take. Returns true if it parsed as an ODID hit.
bool wifi_odid_scanner_test_inject(const uint8_t* frame, size_t len, int16_t rssi);

#endif // ARDUINO

#endif // WIFI_ODID_SCANNER_H
