/*==============================================================================
 * parser.h - BLE command parser public API
 *
 * Parser infrastructure (parsing/CRC/dispatch) and command handlers are
 * decoupled:
 *   - Parser:   parser.c                          (defines the functions here)
 *   - Handlers: handlers/cmd_device.c / cmd_info.c / ...
 *   - Table:    cmd_table.c                       (injected via cmd_table_init)
 *
 * Boot sequence: main.c calls cmd_table_init() -> dr_parser_init() to inject
 * the command table pointer into the parser.
 *============================================================================*/
#ifndef PARSER_H
#define PARSER_H

#include <stdint.h>
#include <stdbool.h>

/* Maximum payload length (excludes TAG) */
#define DR_MAX_DATA 128

/*------------------------------------------------------------------------------
 * Platform interface
 *----------------------------------------------------------------------------*/
typedef struct {
    void (*log)(const char *fmt, ...);
    uint32_t (*tx_bin)(const uint8_t *buf, uint16_t len);  /* len: word (uint16) count */
    bool crc_check;
} dr_platform_if_t;

extern dr_platform_if_t g_plat;
extern bool             g_log_enable;

/*------------------------------------------------------------------------------
 * Parsed command - input passed to handlers
 *----------------------------------------------------------------------------*/
typedef struct {
    char    tag[5];               /* Command TAG (e.g. "mid?") + '\0' */
    uint8_t data[DR_MAX_DATA];    /* Payload bytes following the TAG */
    uint8_t data_len;             /* Valid length of data[] */
} ParsedCmd;

/*------------------------------------------------------------------------------
 * Command table entry - defined in cmd_table.c
 *----------------------------------------------------------------------------*/
typedef struct {
    char tag[5];                              /* TAG: 4 chars + '\0' */
    bool enabled;                             /* false -> rxd: response */
    int  (*handler)(const ParsedCmd *cmd);    /* 1=success, 0=failure */
} CmdEntry;

/*------------------------------------------------------------------------------
 * Parser API
 *----------------------------------------------------------------------------*/

/* Inject command table (called once at boot). */
void dr_parser_init(const CmdEntry *table, uint16_t count);

/* Entry point: invoked from BLE NUS / UART receive callbacks. */
int  dr_cmd_parser(const uint8_t *buf, uint8_t len);

/*------------------------------------------------------------------------------
 * Public utilities for handlers
 *----------------------------------------------------------------------------*/

/* Extract Big-Endian uint16. Returns false if not enough data. */
bool dr_get_u16(const ParsedCmd *cmd, uint8_t word_index, uint16_t *out);

/* Extract null-terminated ASCII string. out must hold at least max_len+1. */
void dr_get_ascii(const ParsedCmd *cmd, uint8_t offset, char *out, uint8_t max_len);

/* CRC16 (Nordic SDK CRC-CCITT variant). p_crc=NULL -> initial 0xFFFF. */
uint16_t dr_crc16_compute(const uint8_t *p_data, uint32_t size, const uint16_t *p_crc);

#endif /* PARSER_H */
