#include "sx127x_pb.h"
#include "sx127x_internal.h"

#include "sdkconfig.h"

#include <pb_encode.h>

#ifdef CONFIG_SX127X_USE_NANOPB

esp_err_t sx127x_send_packet_pb(sx127x_hndl hndl, const pb_field_t fields[],
                                void *src_struct, TickType_t ticks_to_wait) {
  SX127X_CHECK(atomic_load(&hndl->task_state) == SX127X_TASK_RUNNING,
               "task not running", ESP_ERR_INVALID_STATE);

  size_t data_len;
  bool pb_ret = pb_get_encoded_size(&data_len, fields, src_struct);
  SX127X_CHECK(pb_ret == true, "pb_get_encoded_size fail", ESP_ERR_INVALID_ARG);
  SX127X_CHECK(data_len < SX127_MAX_PACKET_LEN, "packet len too long: %d",
               ESP_ERR_INVALID_ARG, data_len);

  pb_byte_t *data = heap_caps_malloc(
      data_len, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_DMA);
  SX127X_CHECK(data != NULL, "malloc error", ESP_ERR_NO_MEM);
  pb_ostream_t ostream = pb_ostream_from_buffer(data, data_len);
  pb_encode(&ostream, fields, src_struct);
  ESP_LOGV(SX127X_TAG, "encoded pb message %d bytes", data_len);

  sx127x_packet_t packet;
  packet.data_len = data_len;
  packet.data     = (char *)data;
  BaseType_t pdRet = xQueueSend(hndl->tx_packet_queue, &packet, ticks_to_wait);
  SX127X_CHECK(pdRet == pdTRUE, "tx queue full", ESP_ERR_TIMEOUT);
  return ESP_OK;
}

#endif