#ifndef MESHTASTIC_EMIT_H
#define MESHTASTIC_EMIT_H

// ============================================================================
// meshtastic_emit.{h,cpp}
//
// Minimum viable Meshtastic LongFast US915 compatibility layer.  Reuses the
// shared SX1262 (via radio_scheduler) — protocol-level packets are framed
// using a stripped-down nanopb-encoded MeshPacket envelope and exchanged
// during the RADIO_MODE_MESHTASTIC time-slice.
//
// PHY (matches Meshtastic firmware Mod_LongFast preset):
//   * Frequency: derived from the channel-hash for "LongFast"
//                → 906.875 MHz on US915 slot 20 (canonical default)
//   * Bandwidth:  250 kHz
//   * SF:         11
//   * CR:         4/5
//   * Sync word:  0x2B
//   * Preamble:   16 symbols
//   * CRC:        on
//
// The wire envelope we emit is a hand-rolled subset of MeshPacket that the
// upstream Meshtastic firmware will accept as a NodeInfo or Data text
// payload. Inbound MeshPackets are parsed back to the minimum useful fields
// and forwarded over the PDL custom mesh as MSG_TYPE_INTEROP_RX.
//
// NodeID:  first 4 bytes of enrollment_get_sensor_id() (already a uint32).
//
// Wire format (best-effort canonical Meshtastic radio-frame):
//   [0..3]   destination_node_id  (LE)         — 0xFFFFFFFF for broadcast
//   [4..7]   source_node_id       (LE)
//   [8..11]  packet_id            (LE)
//   [12]     flags                — bit0 want_ack, bits1-2 hop_limit, bits3-7
//                                    via_mqtt, channel_hash high
//   [13]     channel_hash         — LongFast = 0x08
//   [14..15] reserved
//   [16..]   nanopb-encoded Data { portnum, payload }
// ============================================================================

#include <cstdint>
#include <cstddef>

#define MESHTASTIC_NVS_NS         "pdl_mesht"
#define MESHTASTIC_NVS_ENABLED    "enabled"   // u8
#define MESHTASTIC_NVS_NODE_NAME  "name"      // str (12 chars)

// US915 LongFast canonical frequency — channel-hash derives slot 20
#define MESHTASTIC_FREQ_MHZ       906.875f
#define MESHTASTIC_BW_KHZ         250.0f
#define MESHTASTIC_SF             11
#define MESHTASTIC_CR             5
#define MESHTASTIC_SYNC           0x2B
#define MESHTASTIC_PREAMBLE       16
#define MESHTASTIC_CHANNEL_HASH   0x08

// Standard Meshtastic portnums we care about
#define MT_PORTNUM_TEXT_MSG       1
#define MT_PORTNUM_NODEINFO       4
#define MT_PORTNUM_POSITION       3

// Maximum on-air payload (matches Meshtastic LoRa max)
#define MESHTASTIC_MAX_PACKET     237

// NodeInfo emit cadence
#define MESHTASTIC_NODEINFO_PERIOD_MS  60000

// ---------------------------------------------------------------------------
// Lifecycle
// ---------------------------------------------------------------------------

// Initialise. Reads NVS to determine if Meshtastic emit is enabled at all.
// Returns true if the module is active and should be ticked.
bool meshtastic_init();

// Periodic NodeInfo broadcast — call from the main loop. Internally
// rate-limits to MESHTASTIC_NODEINFO_PERIOD_MS and only emits when the
// scheduler is in MESHTASTIC mode.
bool meshtastic_emit_nodeinfo();

// Send a text-message envelope — call from C2 INTEROP_TX command path.
// Returns false if not enabled, scheduler not in MESHTASTIC mode, or radio
// busy.
bool meshtastic_emit_text(const char* msg);

// Process an inbound packet from the SX1262 (called by the dispatcher when
// the current mode is MESHTASTIC and mesh_receive yields data). Parses,
// re-frames as a MSG_TYPE_INTEROP_RX payload and pushes it onto the PDL
// mesh outbox via mesh_publish_raw().  Returns the number of bytes parsed
// from the input on success, 0 on parse failure, -1 if disabled.
int meshtastic_handle_packet(const uint8_t* buf, size_t len);

// Stats
struct MeshtasticStats {
    uint32_t tx_nodeinfo;
    uint32_t tx_text;
    uint32_t tx_failures;
    uint32_t rx_packets;
    uint32_t rx_parse_failures;
};
void meshtastic_get_stats(MeshtasticStats* out);

// Returns true once meshtastic_init() succeeded and module is enabled.
bool meshtastic_is_enabled();

#ifdef UNIT_TEST
// Native testing helpers — let tests build a NodeInfo without a radio.
extern "C" size_t meshtastic_test_build_nodeinfo(uint8_t* out, size_t out_len);
extern "C" size_t meshtastic_test_build_text(const char* msg, uint8_t* out, size_t out_len);
extern "C" int    meshtastic_test_parse(const uint8_t* in, size_t len,
                                        uint32_t* out_src, uint8_t* out_portnum);
#endif

#endif // MESHTASTIC_EMIT_H
