#ifndef LIBTTN_TTNCORE4_H
#define LIBTTN_TTNCORE4_H

#include <core/types.h>
#include <stdarg.h>

#include "tools/lists.h"
#include "tools/timers.h"
#include "tools/byteswap.h"
#include "tools/string.h"
#include "tools/string32.h"

#include "kernel/ktq.h"

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

#define ttn_bswap16(x) __bswap16(x)
#define ttn_bswap32(x) __bswap32(x)

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

#include <kernel/net/pkb.h>

typedef struct pkb 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_blips;
  struct ttn_timer_t *tmr_next_timer;
  struct ttn_timer_t *tmr_prev_timer;
} ttn_timer_t;

void ttn_glue_timerqueue_init(struct ttn_timerqueue_t *tq);

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 blips, 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*1000, 0);       }
static inline void ttn_glue_timer_start_periodic(ttn_timer_t *tmr, ttn_timer_tick_t ms) { ttn_glue_timer_set(tmr, ms*1000, ms*1000); }

int ttn_core4_timerqueue_checkpoint(struct ttn_timerqueue_t *tq);

static inline uint32_t ttn_glue_getnow_ms(void) {
  return blips64_get() / 1000ULL;
}

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

#include "tools/crc.h"

static inline unsigned int ttn_glue_crc16(const void *data, size_t len) {
  return crc16_buf(data, len, 0xFFFF);
}

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

#include "kernel/kmalloc.h"

#define ttn_glue_malloc(sz) kmalloc(MEMF_DEFAULT, sz)
#define ttn_glue_free       kfree

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

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

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

#include "tools/string.h"

#define ttn_glue_snprintf  snprintf
#define ttn_glue_vsnprintf vsnprintf

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