#ifndef LIBTTN_TTN_H
#define LIBTTN_TTN_H
/****************************************************************************************************************/

#include <stddef.h>
#include <stdbool.h>

#include "ttn/ttn-config.h"

/****************************************************************************************************************/

// Platform specific code must provide this
struct ttn_lnk_handle_t;
typedef void ttn_timerfunc_t(void *data);

#if defined(linux)
#include "ttn/linux/ttn-linux.h"
#elif defined(__CORE4__)
#include "ttn/core4/ttn-core4.h"
#else
#include "ttn/FreeRTOS/ttn-FreeRTOS.h"
#endif

#if defined(__cplusplus)
extern "C" {
#endif

/****************************************************************************************************************/

#define TTN_LOG_NONE     0
#define TTN_LOG_ERROR    1
#define TTN_LOG_WARN     2
#define TTN_LOG_INFO     3  // Occasional informational message
#define TTN_LOG_DEBUG    4  // Major state changes
#define TTN_LOG_VERBOSE  5  // Packet log, but hide token passing
#define TTN_LOG_NOISY    6  // Log! All! The! Packets!

void ttn_glue_log(int level, const char *context, const char *fmt, ...);

#define TTN_LOGE(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_ERROR)   ttn_glue_log(TTN_LOG_ERROR,   "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })
#define TTN_LOGW(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_WARN)    ttn_glue_log(TTN_LOG_WARN,    "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })
#define TTN_LOGI(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_INFO)    ttn_glue_log(TTN_LOG_INFO,    "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })
#define TTN_LOGD(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_DEBUG)   ttn_glue_log(TTN_LOG_DEBUG,   "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })
#define TTN_LOGV(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_VERBOSE) ttn_glue_log(TTN_LOG_VERBOSE, "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })
#define TTN_LOGN(firstarg, ...)  ({ if (ttn->ttn_tracelevel >= TTN_LOG_NOISY)   ttn_glue_log(TTN_LOG_NOISY,   "TTN", "%u: " firstarg, ttn->ttn_myid, ##__VA_ARGS__); })

/****************************************************************************************************************/

void ttn_glue_memdump(int level, const void *start, size_t count);
void ttn_glue_memdumpat(int level, const void *start, uintptr_t at, size_t count);
void ttn_glue_memdumpatpfx(int level, const void *start, uintptr_t at, size_t count, const char *pfx);

/****************************************************************************************************************/

void ttn_glue_random(void *output, size_t output_len);

/****************************************************************************************************************/

// DEBUG: Generate a scope trigger signal
void ttn_glue_trigger(int val);

/****************************************************************************************************************/

enum TTNProcessingResult {
  PacketProcessed,
  PacketDropped,
};

/****************************************************************************************************************/
#if defined(__cplusplus)
}
#endif

#endif
