#ifndef LIBTTN_TTNLINUX_H
#define LIBTTN_TTNLINUX_H

#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>

#include "lists.h"

/****************************************************************************************************************/
// Shamelessly assume the machinery is little endian.
// If it isn't, add fix below.

#define ttn_bswap16(x) __builtin_bswap16(x)
#define ttn_bswap32(x) __builtin_bswap32(x)

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

typedef struct ttn_pkb_t {
  struct list_head pkb_list;
  uint32_t pkb_lsize;
  uint8_t *pkb_link;
} ttn_pkb_t;

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

struct ttn_timer_t;

typedef unsigned int ttn_timer_tick_t;

typedef struct ttn_timerqueue_t {
  struct ttn_timer_t *tq_first;
} ttn_timerqueue_t;

typedef struct ttn_timer_t {
  struct ttn_timerqueue_t *tmr_queue;
  ttn_timerfunc_t *tmr_callback;
  struct ttn_lnk_handle_t *tmr_data;
  ttn_timer_tick_t tmr_expires;
  ttn_timer_tick_t tmr_ms;
  struct ttn_timer_t *tmr_next_timer;
  struct ttn_timer_t *tmr_prev_timer;
} ttn_timer_t;

ttn_timer_tick_t ttn_glue_getnow_ms(void);

void ttn_glue_timer_init(ttn_timerqueue_t *tq, ttn_timer_t *tmr, ttn_timerfunc_t *func, void *data);
void ttn_glue_timer_close(ttn_timer_t *tmr);
void ttn_glue_timer_stop(ttn_timer_t *tmr);
void ttn_glue_timer_set(ttn_timer_t *tmr, ttn_timer_tick_t ms, unsigned int reload);

static inline void ttn_glue_timer_start_single(ttn_timer_t *tmr, ttn_timer_tick_t ms)   { ttn_glue_timer_set(tmr, ms, 0);  }
static inline void ttn_glue_timer_start_periodic(ttn_timer_t *tmr, ttn_timer_tick_t ms) { ttn_glue_timer_set(tmr, ms, ms); }

int ttn_linux_timerqueue_checkpoint(struct ttn_timerqueue_t *tq);

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

unsigned int ttn_glue_crc16(const void *data, size_t len);

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

#include <malloc.h>

#define ttn_glue_malloc malloc
#define ttn_glue_free   free

unsigned int ttn_linux_get_max_buffer_pool_use_count(void);
unsigned int ttn_linux_get_current_buffer_pool_use_count(void);

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

void ttn_glue_log_begin(void);
void ttn_glue_log_end(void);

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

int mini_snprintf(char *buffer, unsigned int buffer_len, const char *fmt, ...);
#define ttn_glue_snprintf  mini_snprintf

int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list va);
#define ttn_glue_vsnprintf mini_vsnprintf

/****************************************************************************************************************/
#endif
