/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * LoRa modem abstraction layer.
 * Wraps Zephyr's lora_driver_api with application-level configuration.
 */
#ifndef LORA_MODEM_H
#define LORA_MODEM_H

#include <stdint.h>
#include <stddef.h>
#include <zephyr/kernel.h>

/**
 * @brief Runtime radio parameters.
 *
 * All fields are in user-friendly units.  Modified at runtime via
 * lora_modem_set_params() / lora_modem_set_freq(); read via
 * lora_modem_get_params().
 */
struct lora_radio_params {
	uint32_t freq_hz;      /**< Center frequency in Hz */
	uint8_t  sf;           /**< Spreading factor (7-12) */
	uint16_t bw_khz;       /**< Bandwidth in kHz (e.g., 62 means 62.5 kHz). Supported values: 7, 10, 15, 20, 31, 41, 62, 125, 200, 250, 400, 500, 800, 1000, 1600 */
	uint8_t  cr;           /**< Coding rate denominator (5..8, meaning 4/5..4/8) */
	int8_t   tx_power;     /**< TX power in dBm */
	uint8_t  preamble_len; /**< Preamble length in symbols */
};

/**
 * @brief Initialize and configure the LoRa radio.
 *
 * Loads compile-time Kconfig defaults into the runtime params struct
 * and applies them.  Call once at startup before any send/recv.
 *
 * @return 0 on success, negative errno on failure.
 */
int lora_modem_init(void);

/**
 * @brief Get the current radio parameters.
 *
 * @param params  Output: filled with current settings.
 */
void lora_modem_get_params(struct lora_radio_params *params);

/**
 * @brief Set all radio parameters at once.
 *
 * Parameters are stored for use on the next send/recv call.
 * The radio is NOT immediately reconfigured; the change takes effect
 * at the start of the next lora_modem_send() or lora_modem_recv() call.
 *
 * @param params  New parameter values.
 * @return        0 on success, -EINVAL if a parameter is out of range.
 */
int lora_modem_set_params(const struct lora_radio_params *params);

/**
 * @brief Change only the center frequency.
 *
 * Convenience wrapper around lora_modem_set_params() for the common
 * case of a frequency-only change.
 *
 * @param freq_hz  New center frequency in Hz.
 * @return         0 on success, -EINVAL if out of range.
 */
int lora_modem_set_freq(uint32_t freq_hz);

/**
 * @brief Transmit a packet over LoRa.
 *
 * @param data  Payload bytes.
 * @param len   Payload length (must be <= CONFIG_LORAMODEM_MAX_PACKET_SIZE).
 * @return      0 on success, negative errno on failure.
 */
int lora_modem_send(const uint8_t *data, size_t len);

/**
 * @brief Receive a packet from LoRa (blocking).
 *
 * @param buf       Buffer for received payload.
 * @param buf_size  Size of @p buf.
 * @param timeout   How long to wait (use K_FOREVER to wait indefinitely).
 * @param rssi_out  If non-NULL, receives RSSI of the packet (dBm).
 * @param snr_out   If non-NULL, receives SNR of the packet (dB).
 * @return          Number of bytes received (>= 0), or negative errno on error/timeout.
 */
int lora_modem_recv(uint8_t *buf, size_t buf_size, k_timeout_t timeout,
		    int16_t *rssi_out, int8_t *snr_out);

#endif /* LORA_MODEM_H */
