#include "ds.h"

#include <string.h>

#define QUEUE_AT(_pq, _idx) ((char *)((_pq)->entries) + ((_pq)->entry_size * (_idx)))

RT_DLLEXPORT rt_queue rtCreateQueue(uint64_t capacity, void *memory, uint64_t entry_size) {
    rt_queue q = {.entries    = memory,
                  .entry_size = entry_size,
                  .capacity   = capacity,
                  .head       = 0,
                  .tail       = 0};
    return q;
}

RT_DLLEXPORT rt_result rtQueuePush(rt_queue *queue, const void *element) {
    if (rtQueueIsFull(queue))
        return RT_OUT_OF_MEMORY;
    char *dest = QUEUE_AT(queue, queue->tail);
    memcpy(dest, element, queue->entry_size);

    queue->tail = (queue->tail + 1) % queue->capacity;
    return RT_SUCCESS;
}

RT_DLLEXPORT rt_result rtQueuePop(rt_queue *queue, void *dst) {
    if (rtQueueIsEmpty(queue))
        return RT_INVALID_VALUE;
    const char *src = QUEUE_AT(queue, queue->head);
    memcpy(dst, src, queue->entry_size);
    queue->head = (queue->head + 1) % queue->capacity;
    return RT_SUCCESS;
}