#ifndef PDL_BAND_BRIDGE_H
#define PDL_BAND_BRIDGE_H

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

// ============================================================================
// Band-bridge module
//
// A T1 sensor running this module can accept a STANAG-4586 command over its
// 915 MHz LoRa mesh (msg_type 0x0A UAV_CMD) AND re-transmit it on whatever
// band the target drone actually listens on — 433 / 868 / 2.4 / 5.8 GHz.
//
// This is the last-hop relay: the T2 mesh coordinator picks this sensor as
// the final hop when the drone's target band matches an available radio
// here. Our job is:
//   1. Verify the inbound STANAG frame is well-formed + HMAC-valid.
//   2. Check that TX on the destination band won't blow the duty budget.
//   3. Transmit the frame on the destination band.
//   4. Optionally wait up to 500 ms for the drone's ACK on the same band.
//   5. Forward the ACK back through the LoRa mesh to the originator.
//
// Gated by PDL_ENABLE_BAND_BRIDGE. If undefined, every function is a no-op
// stub so the rest of the firmware compiles unchanged.
// ============================================================================

#ifndef PDL_MSG_TYPE_BAND_BRIDGE
#define PDL_MSG_TYPE_BAND_BRIDGE 0x0F   // mesh-ack shape distinct from 0x0B/0x0C
#endif

#ifndef PDL_MRSH_MSG_TYPE_MESH_ACK
// MESH_ACK byte ‒ owned by the concurrent mesh_routing agent. We assume
// 0x10 here to avoid overlap with UAV_CMD (0x0A), UAV_ACK (0x0B),
// UAV_TELEM (0x0C), UAV_PAIR_REQ (0x0D), UAV_PAIR_RSP (0x0E), or this
// module's own BAND_BRIDGE route-marker (0x0F). If mesh_routing picks a
// different value, override via -DPDL_MRSH_MSG_TYPE_MESH_ACK=<byte> in
// platformio.ini.
#define PDL_MRSH_MSG_TYPE_MESH_ACK 0x10
#endif

enum class BridgeStatus : uint8_t {
    DELIVERED         = 0,
    HMAC_INVALID      = 1,
    DUTY_EXCEEDED     = 2,
    NO_TARGET_RADIO   = 3,
    TX_FAILED         = 4,
    NO_ACK_FROM_DRONE = 5,
    NOT_ENABLED       = 6,   // module compiled out
};

struct BridgeResult {
    BridgeStatus status;
    uint16_t     sequence;       // echoed from the inbound frame
    int          drone_rssi;     // last RSSI on the dst band (after ACK RX)
};

// ---------------------------------------------------------------------------
// Initialize the bridge. Call from setup() after radio_abstraction_init().
// Pass the shared HMAC key (32 bytes; derived from the operator policy
// manifest). If key is NULL, HMAC is not enforced (test-mode only — never
// production).
// ---------------------------------------------------------------------------
void band_bridge_init(const uint8_t* hmac_key, size_t hmac_key_len);

// ---------------------------------------------------------------------------
// Relay a frame from `src_band` to `dst_band`. `frame` MUST be a 32-byte
// STANAG command (with or without leading 0x0A msg_type prefix accepted).
// Returns the BridgeResult.
// ---------------------------------------------------------------------------
BridgeResult band_bridge_relay(BandId src_band, BandId dst_band,
                               const uint8_t* frame, size_t len,
                               bool require_ack);

// ---------------------------------------------------------------------------
// Entry point called from the T2-mesh-coordinator-owned mesh_routing.cpp
// when a route terminates at this node with a UAV_CMD destined for the
// drone's actual band. drone_band is looked up from the route header.
//
// On completion emits a 16-byte MESH_ACK frame back onto the 915 mesh so
// the originating commander sees DELIVERED / DROPPED status.
// ---------------------------------------------------------------------------
bool band_bridge_handle_route_delivery(const uint8_t* frame, size_t len,
                                       BandId drone_band);

// ---------------------------------------------------------------------------
// Build a MESH_ACK frame (same 16-byte shape as mesh_routing owner uses).
// Returns bytes written.
// ---------------------------------------------------------------------------
size_t band_bridge_build_mesh_ack(uint16_t sequence, BridgeStatus status,
                                  uint8_t* out, size_t out_len);

#endif // PDL_BAND_BRIDGE_H
