#ifndef BLE_PROXY_CHARS_H
#define BLE_PROXY_CHARS_H

// ============================================================================
// ble_proxy_chars.h — Add ProxyTx + ProxyRx GATT characteristics
//
// The in-flight ble_companion module (ble_companion.{h,cpp}) creates the
// primary BLE service for the T1 sensor. This module bolts two ADDITIONAL
// characteristics onto that same service so the bonded phone can tunnel
// arbitrary OpenForge C2 API calls through LoRa via the bonded sensor:
//
//     ProxyTx   pdl0008   write          phone → sensor: chunked C2 REQ
//     ProxyRx   pdl0009   notify         sensor → phone: chunked C2 RSP
//
// Both carry the SAME 24-byte chunk header as MSG_TYPE_PAYLOAD_CHUNK / 0x14
// (see payload_buffer.h). ProxyTx writes are forwarded into
// c2_proxy_tunnel.cpp via c2_proxy_handle_ble_write().
//
// Integration hook
// ----------------
// The companion agent's ble_companion.cpp owns the BLEService creation. After
// it has registered its existing characteristics, it must call:
//
//     #include "ble_proxy_chars.h"
//     ble_proxy_register(svc);   // svc is the NimBLE BLEService*
//
// ble_proxy_register() is documented in PROXY_TUNNEL_INTEGRATION_NOTES.md.
//
// The BLEService* type is forward-declared opaquely so the header is
// translation-unit safe even if NimBLE-Arduino isn't on the include path.
// The .cpp file pulls in <NimBLEDevice.h> and casts.
// ============================================================================

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

// Service handle is passed as opaque void* to avoid header-visible NimBLE
// dependency. The .cpp casts to the right NimBLE type.

// ---------------------------------------------------------------------------
// GATT UUIDs (string form — 128-bit). Match the existing pdl0001..pdl0007
// numbering pattern; new chars get pdl0008 / pdl0009.
// ---------------------------------------------------------------------------
// FIXED 2026-07-26: see ble_companion.h — "pdl0"/"pdl" placeholders are not
// valid hex, NimBLE-Arduino collapsed all custom UUIDs to one value.
#define BLE_PDL_CHAR_PROXY_TX_UUID  "12345678-0000-4001-8001-000000000108"  // pdl0008
#define BLE_PDL_CHAR_PROXY_RX_UUID  "12345678-0000-4001-8001-000000000109"  // pdl0009

// Max bytes an Android client may write in a single ProxyTx GATT write —
// matches the C2_PROXY_HDR_LEN + C2_PROXY_MAX_DATA bound in c2_proxy_tunnel.h.
// (BLE 5 with extended-length ATT supports up to 244-byte writes by default,
// 244 ≥ 24 + 200 = 224, so a single chunk fits in a single GATT write.)
#define BLE_PROXY_MAX_WRITE_BYTES   224

// ---------------------------------------------------------------------------
// Stats snapshot
// ---------------------------------------------------------------------------
struct BleProxyStats {
    uint32_t proxy_tx_writes;        // ProxyTx GATT writes received
    uint32_t proxy_tx_writes_bad;    // rejected (wrong size, not authed, …)
    uint32_t proxy_rx_notifies;      // ProxyRx notifications emitted
    uint32_t proxy_rx_notify_drops;  // notify-failed (peer disconnected, etc.)
    bool     registered;
};

// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------

// Register ProxyTx + ProxyRx onto an existing BLE service. Idempotent: a
// second call is a no-op. Must be called AFTER the companion agent has
// finished adding its existing characteristics, and BEFORE service start().
// Returns true on success.
//
// At runtime the .cpp implementation also wires the
// c2_proxy_ble_notify(buf, len) hook by overriding the weak default — so
// callers of c2_proxy_ble_notify() will route notifications through the
// ProxyRx characteristic without further wiring.
bool ble_proxy_register(void* svc);

// Snapshot stats. out must be non-null.
void ble_proxy_get_stats(BleProxyStats* out);

#ifdef UNIT_TEST
// Reset module state — host-test only. NimBLE objects are mocked.
void ble_proxy_test_reset();
// Simulate a ProxyTx GATT write (host tests).
bool ble_proxy_test_inject_write(const uint8_t* buf, size_t len);
// Pop the next queued ProxyRx notify into out_buf (host tests). Returns the
// length, or 0 if no notify is queued. out_buf must be ≥ BLE_PROXY_MAX_WRITE_BYTES.
size_t ble_proxy_test_pop_notify(uint8_t* out_buf, size_t cap);
#endif

#endif // BLE_PROXY_CHARS_H
