/*
 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdlib.h>
#include "internal/event_queue.h"
#include "ssl_local.h"

struct ossl_event_queue_st {
    PRIORITY_QUEUE_OF(OSSL_EVENT) * timed_events;
    PRIORITY_QUEUE_OF(OSSL_EVENT) * now_events;
};

static int event_compare_times(const OSSL_EVENT *a, const OSSL_EVENT *b)
{
    return ossl_time_compare(a->when, b->when);
}

static int event_compare_priority(const OSSL_EVENT *a, const OSSL_EVENT *b)
{
    if (a->priority > b->priority)
        return -1;
    if (a->priority < b->priority)
        return 1;
    return 0;
}

OSSL_EVENT_QUEUE *ossl_event_queue_new(void)
{
    OSSL_EVENT_QUEUE *r = OPENSSL_malloc(sizeof(*r));

    if (r != NULL) {
        r->timed_events = ossl_pqueue_OSSL_EVENT_new(&event_compare_times);
        r->now_events = ossl_pqueue_OSSL_EVENT_new(&event_compare_priority);
        if (r->timed_events == NULL || r->now_events == NULL) {
            ossl_event_queue_free(r);
            return NULL;
        }
    }
    return r;
}

void ossl_event_free(OSSL_EVENT *event)
{
    if (event != NULL) {
        if (event->flag_dynamic)
            OPENSSL_free(event);
        else
            event->queue = NULL;
    }
}

static void event_queue_free(PRIORITY_QUEUE_OF(OSSL_EVENT) * queue)
{
    OSSL_EVENT *e;

    if (queue != NULL) {
        while ((e = ossl_pqueue_OSSL_EVENT_pop(queue)) != NULL)
            ossl_event_free(e);
        ossl_pqueue_OSSL_EVENT_free(queue);
    }
}

void ossl_event_queue_free(OSSL_EVENT_QUEUE *queue)
{
    if (queue != NULL) {
        event_queue_free(queue->now_events);
        event_queue_free(queue->timed_events);
        OPENSSL_free(queue);
    }
}

static ossl_inline int event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event)
{
    PRIORITY_QUEUE_OF(OSSL_EVENT) *pq = ossl_time_compare(event->when, ossl_time_now()) <= 0
        ? queue->now_events
        : queue->timed_events;

    if (ossl_pqueue_OSSL_EVENT_push(pq, event, &event->ref)) {
        event->queue = pq;
        return 1;
    }
    return 0;
}

static ossl_inline void ossl_event_set(OSSL_EVENT *event, uint32_t type, uint32_t priority,
    OSSL_TIME when, void *ctx,
    void *payload, size_t payload_size)
{
    event->type = type;
    event->priority = priority;
    event->when = when;
    event->ctx = ctx;
    event->payload = payload;
    event->payload_size = payload_size;
}

OSSL_EVENT *ossl_event_queue_add_new(OSSL_EVENT_QUEUE *queue,
    uint32_t type, uint32_t priority,
    OSSL_TIME when, void *ctx,
    void *payload, size_t payload_size)
{
    OSSL_EVENT *e = OPENSSL_malloc(sizeof(*e));

    if (e == NULL || queue == NULL) {
        OPENSSL_free(e);
        return NULL;
    }

    ossl_event_set(e, type, priority, when, ctx, payload, payload_size);
    e->flag_dynamic = 1;
    if (event_queue_add(queue, e))
        return e;
    OPENSSL_free(e);
    return NULL;
}

int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event,
    uint32_t type, uint32_t priority,
    OSSL_TIME when, void *ctx,
    void *payload, size_t payload_size)
{
    if (event == NULL || queue == NULL)
        return 0;
    ossl_event_set(event, type, priority, when, ctx, payload, payload_size);
    event->flag_dynamic = 0;
    return event_queue_add(queue, event);
}

int ossl_event_queue_remove(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event)
{
    if (event != NULL && event->queue != NULL) {
        ossl_pqueue_OSSL_EVENT_remove(event->queue, event->ref);
        event->queue = NULL;
    }
    return 1;
}

OSSL_TIME ossl_event_time_until(const OSSL_EVENT *event)
{
    if (event == NULL)
        return ossl_time_infinite();
    return ossl_time_subtract(event->when, ossl_time_now());
}

OSSL_TIME ossl_event_queue_time_until_next(const OSSL_EVENT_QUEUE *queue)
{
    if (queue == NULL)
        return ossl_time_infinite();
    if (ossl_pqueue_OSSL_EVENT_num(queue->now_events) > 0)
        return ossl_time_zero();
    return ossl_event_time_until(ossl_pqueue_OSSL_EVENT_peek(queue->timed_events));
}

int ossl_event_queue_postpone_until(OSSL_EVENT_QUEUE *queue,
    OSSL_EVENT *event,
    OSSL_TIME when)
{
    if (ossl_event_queue_remove(queue, event)) {
        event->when = when;
        return event_queue_add(queue, event);
    }
    return 0;
}

int ossl_event_queue_get1_next_event(OSSL_EVENT_QUEUE *queue,
    OSSL_EVENT **event)
{
    OSSL_TIME now = ossl_time_now();
    OSSL_EVENT *e;

    /* Check for expired timer based events and convert them to now events */
    while ((e = ossl_pqueue_OSSL_EVENT_peek(queue->timed_events)) != NULL
        && ossl_time_compare(e->when, now) <= 0) {
        e = ossl_pqueue_OSSL_EVENT_pop(queue->timed_events);
        if (!ossl_pqueue_OSSL_EVENT_push(queue->now_events, e, &e->ref)) {
            e->queue = NULL;
            return 0;
        }
    }

    /*
     * Get next event from the now queue.
     * The pop returns NULL when there is none.
     */
    *event = ossl_pqueue_OSSL_EVENT_pop(queue->now_events);
    return 1;
}
