/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include <autoconf.h>
#include <sel4test-driver/gen_config.h>
#include <sel4/sel4.h>
#include "timer.h"
#include <utils/util.h>
#include <sel4testsupport/testreporter.h>

struct sel4test_ack_data {
    driver_env_t env;
    int nth_timer;
};
typedef struct sel4test_ack_data sel4test_ack_data_t;

/* A pending timeout requests from tests */
static bool timeServer_timeoutPending = false;
static timeout_type_t timeServer_timeoutType;

static int timeout_cb(uintptr_t token)
{
    seL4_Signal((seL4_CPtr) token);

    if (timeServer_timeoutType != TIMEOUT_PERIODIC) {
        timeServer_timeoutPending = false;
    }
    return 0;
}

static int ack_timer_interrupts(void *ack_data)
{
    ZF_LOGF_IF(!ack_data, "ack_data is NULL");
    sel4test_ack_data_t *timer_ack_data = (sel4test_ack_data_t *) ack_data;

    driver_env_t env = timer_ack_data->env;
    int nth_timer = timer_ack_data->nth_timer;

    /* Acknowledge the interrupt handler */
    int error = seL4_IRQHandler_Ack(env->timer_irqs[nth_timer].handler_path.capPtr);
    ZF_LOGF_IF(error, "Failed to acknowledge timer IRQ handler");

    ps_free(&env->ops.malloc_ops, sizeof(sel4test_ack_data_t), ack_data);
    return error;
}

void handle_timer_interrupts(driver_env_t env, seL4_Word badge)
{
    int error = 0;
    while (badge) {
        seL4_Word badge_bit = CTZL(badge);
        sel4test_ack_data_t *ack_data = NULL;
        error = ps_calloc(&env->ops.malloc_ops, 1, sizeof(sel4test_ack_data_t), (void **) &ack_data);
        ZF_LOGF_IF(error, "Failed to allocate memory for ack token");
        ack_data->env = env;
        ack_data->nth_timer = (int) badge_bit;
        env->timer_cbs[badge_bit].callback(env->timer_cbs[badge_bit].callback_data,
                                           ack_timer_interrupts, ack_data);
        badge &= ~BIT(badge_bit);
    }
}

void wait_for_timer_interrupt(driver_env_t env)
{
    if (config_set(CONFIG_HAVE_TIMER)) {
        seL4_Word sender_badge;
        seL4_Wait(env->timer_notification.cptr, &sender_badge);
        if (sender_badge) {
            handle_timer_interrupts(env, sender_badge);
        }
    } else {
        ZF_LOGF("There is no timer configured for this target");
    }
}

void timeout(driver_env_t env, uint64_t ns, timeout_type_t timeout_type)
{
    if (config_set(CONFIG_HAVE_TIMER)) {
        ZF_LOGD_IF(timeServer_timeoutPending, "Overwriting a previous timeout request\n");
        timeServer_timeoutType = timeout_type;
        int error = tm_register_cb(&env->tm, timeout_type, ns, 0,
                                   TIMER_ID, timeout_cb, env->timer_notify_test.cptr);
        if (error == ETIME) {
            error = timeout_cb(env->timer_notify_test.cptr);
        } else {
            timeServer_timeoutPending = true;
        }
        ZF_LOGF_IF(error != 0, "register_cb failed");
    } else {
        ZF_LOGF("There is no timer configured for this target");
    }
}

void timer_reset(driver_env_t env)
{
    if (config_set(CONFIG_HAVE_TIMER)) {
        int error = tm_deregister_cb(&env->tm, TIMER_ID);
        ZF_LOGF_IF(error, "ltimer_rest failed");
        timeServer_timeoutPending = false;
    } else {
        ZF_LOGF("There is no timer configured for this target");
    }
}

uint64_t timestamp(driver_env_t env)
{
    uint64_t time = 0;
    if (config_set(CONFIG_HAVE_TIMER)) {
        int error = ltimer_get_time(&env->ltimer, &time);
        ZF_LOGF_IF(error, "failed to get time");

    } else {
        ZF_LOGF("There is no timer configured for this target");
    }
    return time;
}

void timer_cleanup(driver_env_t env)
{
    ZF_LOGF_IF(!config_set(CONFIG_HAVE_TIMER), "There is no timer configured for this target");
    tm_free_id(&env->tm, TIMER_ID);
    timeServer_timeoutPending = false;
}
