#ifndef MQTT_CLIENT_H
#define MQTT_CLIENT_H

// ============================================================================
// mqtt_client.{h,cpp}
//
// MQTT-over-WiFi-STA bridge for T1 sensors.  The WiFi promiscuous sniffer
// keeps running in parallel; once STA associates, the channel-hopper is
// pinned to the AP's channel so packet capture and TX coexist on the same
// 802.11 channel.
//
// All configuration lives in NVS namespace "pdl_mqtt":
//
//   ssid          (str)   WiFi SSID
//   psk           (str)   WiFi password
//   broker_host   (str)   MQTT broker hostname or IP
//   broker_port   (u16)   MQTT broker port (default 1883, 8883 for TLS)
//   client_id     (str)   override clientid (default "pdl-<sensor_name>")
//   tls           (u8)    0 = plain, 1 = TLS (default 0)
//   user          (str)   optional auth user
//   pass          (str)   optional auth password
//   ca_cert       (blob)  optional CA cert PEM (only used if tls=1)
//
// Topics published:
//   pdl/<sensor_name>/detection   — JSON detection events
//   pdl/<sensor_name>/networks    — observed 802.11 networks
//   pdl/<sensor_name>/nll         — Markov NLL telemetry
//   pdl/<sensor_name>/alert       — composite + jamming alerts (retain=1)
//   pdl/<sensor_name>/health      — periodic health beacon
//
// Topics subscribed:
//   pdl/<sensor_name>/cmd         — 32-byte CMD_PACKET wire-format payload
//                                    (forwarded verbatim to handleIncomingCommand)
//
// QoS 1 on all publishes; retain on alert.  Runs in its own FreeRTOS task
// at LOW priority (tskIDLE_PRIORITY+1) so it never starves the main loop.
// On the native (test) build the entire module is a no-op stub that
// exercises only topic-formatting code paths.
// ============================================================================

#include <cstdint>
#include <cstddef>
#include "config.h"

#define MQTT_NVS_NS         "pdl_mqtt"
#define MQTT_NVS_SSID       "ssid"
#define MQTT_NVS_PSK        "psk"
#define MQTT_NVS_BROKER     "broker_host"
#define MQTT_NVS_PORT       "broker_port"
#define MQTT_NVS_CLIENT     "client_id"
#define MQTT_NVS_TLS        "tls"
#define MQTT_NVS_USER       "user"
#define MQTT_NVS_PASS       "pass"
#define MQTT_NVS_CA         "ca_cert"

#define MQTT_DEFAULT_PORT      1883
#define MQTT_DEFAULT_TLS_PORT  8883

// ---------------------------------------------------------------------------
// Lifecycle
// ---------------------------------------------------------------------------
void mqtt_init();

// Periodic status heartbeat on pdl/<sensor>/status — call every loop() cycle.
//
// Without this, MQTT traffic is emitted only as a side effect of activity
// (a VQC score or a detection), so a healthy-but-quiet unit is
// indistinguishable from a dead one on the broker. A fixed-cadence heartbeat
// makes absence meaningful, which is the prerequisite for monitoring the fleet
// from the broker alone rather than polling six DHCP-assigned addresses.
void mqtt_tick();

// Heartbeat cadence. Matches the C2 health interval so both transports report
// liveness on the same rhythm and a gap in one is directly comparable to the
// other.
#define MQTT_STATUS_INTERVAL_MS  60000u

// True iff WiFi STA is up AND PubSubClient::connected() is true.
bool mqtt_is_connected();

// Returns true if NVS contained at least an ssid + broker host (i.e. MQTT
// is configured to come up at all). Useful for build-time gating.
bool mqtt_is_configured();

// Publish helpers — all return false if not connected.
bool mqtt_publish_detection(const DetectionEvent& evt);
bool mqtt_publish_text(const char* topic_suffix, const char* json_payload);

// Topic builder (exposed for tests). Writes into out, NUL-terminated.
// Returns the number of bytes written excluding the NUL.
size_t mqtt_format_topic(char* out, size_t out_len,
                         const char* sensor_name, const char* suffix);

// Stats
struct MqttStats {
    uint32_t connect_ok;
    uint32_t connect_fail;
    uint32_t pub_detection;
    uint32_t pub_text;
    uint32_t pub_failures;
    uint32_t cmd_received;
};
void mqtt_get_stats(MqttStats* out);

// Native-test entry: format event as JSON detection blob.
size_t mqtt_format_detection_json(const DetectionEvent& evt,
                                  char* out, size_t out_len);

#endif // MQTT_CLIENT_H
