/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <utils/sglib.h>
#include <platsupport/tqueue.h>

static int cmp(uint64_t a, uint64_t b)
{
     if (a > b) {
         return 1;
     } else if (a < b) {
         return -1;
     } else {
         return 0;
     }
}

#define TIMEOUT_CMP(t1, t2) (cmp(t1->timeout.abs_time, t2->timeout.abs_time))

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(tqueue_node_t, TIMEOUT_CMP, next)
SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(tqueue_node_t, TIMEOUT_CMP, next)
#pragma GCC diagnostic pop

static tqueue_node_t *head(tqueue_node_t *list)
{
    struct sglib_tqueue_node_t_iterator it;
    return sglib_tqueue_node_t_it_init(&it, list);
}

int tqueue_alloc_id(tqueue_t *tq, unsigned int *id)
{
    if (!tq || !id) {
        return EINVAL;
    }

    for (int i = 0; i < tq->n; i++) {
        if (!tq->array[i].allocated) {
            tq->array[i].allocated = true;
            *id = i;
            return 0;
        }
    }

    ZF_LOGE("Out of timer client ids\n");
    return ENOMEM;
}

int tqueue_alloc_id_at(tqueue_t *tq, unsigned int id)
{
    if (!tq || id >= tq->n) {
        return  EINVAL;
    }

    if (tq->array[id].allocated) {
        return EADDRINUSE;
    }

    tq->array[id].allocated = true;
    return 0;
}

int tqueue_free_id(tqueue_t *tq, unsigned int id)
{
    if (!tq) {
        return EINVAL;
    }

    if (id < 0 || id >= tq->n) {
        ZF_LOGE("Invalid id");
        return EINVAL;
    }

    if (!tq->array[id].allocated) {
        ZF_LOGW("Freeing unallocated id");
        return EINVAL;
    }

    /* remove from queue */
    if (tq->array[id].active) {
        sglib_tqueue_node_t_delete(&tq->queue, &tq->array[id]);
        tq->array[id].active = false;
    }

    tq->array[id].allocated = false;
    return 0;
}

int tqueue_register(tqueue_t *tq, unsigned int id, timeout_t *timeout)
{
    if (!tq) {
        return EINVAL;
    }

    if (id < 0 || id > tq->n || !tq->array[id].allocated) {
        ZF_LOGE("invalid id");
        return EINVAL;
    }

    /* delete the callback from the queue if its present */
    if (tq->array[id].active) {
        sglib_tqueue_node_t_delete(&tq->queue, &tq->array[id]);
    }

    /* update node */
    tq->array[id].active = true;
    tq->array[id].timeout = *timeout;

    /* add to data structure */
    sglib_tqueue_node_t_add(&tq->queue, &tq->array[id]);
    return 0;
}

int tqueue_cancel(tqueue_t *tq, unsigned int id) {

    if (!tq) {
        return EINVAL;
    }

    /* iterate through the list until we find that id */
    if (id < 0 || id > tq->n) {
        ZF_LOGE("Invalid id");
        return EINVAL;
    }

    /* delete the callback from the queue if its present */
    if (tq->array[id].active) {
        sglib_tqueue_node_t_delete(&tq->queue, &tq->array[id]);
    }

    tq->array[id].active = false;
    return 0;
}

int tqueue_update(tqueue_t *tq, uint64_t curr_time, uint64_t *next_time) {
    if (!tq) {
        return EINVAL;
    }

    /* keep checking the head of this queue */
    tqueue_node_t *t = head(tq->queue);
    while (t != NULL && t->timeout.abs_time <= curr_time) {
        if (t->active) {
            t->timeout.callback(t->timeout.token);
        }

        /* check if it is active again, as callback may have deactivated the timeout */
        if (t->active) {
            sglib_tqueue_node_t_delete(&tq->queue, t);
            if (t->timeout.period > 0) {
                t->timeout.abs_time += t->timeout.period;
                sglib_tqueue_node_t_add(&tq->queue, t);
            } else {
                t->active = false;
            }
        }
        t = head(tq->queue);
    }

    if (next_time) {
        if (t) {
            *next_time = t->timeout.abs_time;
        } else {
            *next_time = 0;
        }
    }
    return 0;
}

int tqueue_init_static(tqueue_t *tq, ps_malloc_ops_t *mops, int size)
{
    if (!tq || !mops) {
        return EINVAL;
    }

    if (size <= 0) {
        return EINVAL;
    }

    /* initialise the list */
    tq->n = size;
    int error = ps_calloc(mops, size, sizeof(tqueue_node_t), (void **) &tq->array);
    if (error) {
        return ENOMEM;
    }

    assert(tq->array != NULL);

    /* noone currently in the queue */
    tq->queue = NULL;

    return 0;
}
