// Copyright 2018 The Fuchsia Authors.All rights reserved.
// Use of this source code is governed by a BSD - style license that can be
// found in the LICENSE file.

#include <lib/async-testutils/test_loop_dispatcher.h>

#include <zircon/assert.h>
#include <zircon/syscalls.h>

#define TO_NODE(type, ptr) ((list_node_t*)&ptr->state)
#define FROM_NODE(type, ptr) ((type*)((char*)(ptr)-offsetof(type, state)))

namespace async {

namespace {

// Convenience functions for task, wait, and list node management.
inline list_node_t* WaitToNode(async_wait_t* wait) {
    return TO_NODE(async_wait_t, wait);
}

inline async_wait_t* NodeToWait(list_node_t* node) {
    return FROM_NODE(async_wait_t, node);
}

inline list_node_t* TaskToNode(async_task_t* task) {
    return TO_NODE(async_task_t, task);
}

inline async_task_t* NodeToTask(list_node_t* node) {
    return FROM_NODE(async_task_t, node);
}

inline void InsertTask(list_node_t* task_list, async_task_t* task) {
    list_node_t* node;
    for (node = task_list->prev; node != task_list; node = node->prev) {
        if (task->deadline >= NodeToTask(node)->deadline)
            break;
    }
    list_add_after(node, TaskToNode(task));
}

} // namespace

TestLoopDispatcher::TestLoopDispatcher(zx::time* current_time)
    : current_time_(current_time) {
    ZX_DEBUG_ASSERT(current_time);
    list_initialize(&wait_list_);
    list_initialize(&task_list_);
    zx_status_t status = zx::port::create(0u, &port_);
    ZX_ASSERT_MSG(status == ZX_OK, "status=%d", status);
}

TestLoopDispatcher::~TestLoopDispatcher() = default;

zx_status_t TestLoopDispatcher::BeginWait(async_wait_t* wait) {
    ZX_DEBUG_ASSERT(wait);
    list_add_head(&wait_list_, WaitToNode(wait));

    zx_status_t status = zx_object_wait_async(wait->object, port_.get(),
                                              reinterpret_cast<uintptr_t>(wait),
                                              wait->trigger,
                                              ZX_WAIT_ASYNC_ONCE);

    if (status != ZX_OK) {
        // In this rare condition, the wait failed. Since a dispatched handler will
        // never be invoked on the wait object, we remove it ourselves.
        list_delete(WaitToNode(wait));
    }
    return status;
}

zx_status_t TestLoopDispatcher::CancelWait(async_wait_t* wait) {
    ZX_DEBUG_ASSERT(wait);
    zx_status_t status = port_.cancel(wait->object, reinterpret_cast<uintptr_t>(wait));
    if (status == ZX_OK) {
        list_delete(WaitToNode(wait));
    }
    return status;
}

zx_status_t TestLoopDispatcher::PostTask(async_task_t* task) {
    ZX_DEBUG_ASSERT(task);
    InsertTask(&task_list_, task);
    return ZX_OK;
}

zx_status_t TestLoopDispatcher::CancelTask(async_task_t* task) {
    ZX_DEBUG_ASSERT(task);
    list_node_t* node = TaskToNode(task);
    if (!list_in_list(node)) {
        return ZX_ERR_NOT_FOUND;
    }
    list_delete(node);
    return ZX_OK;
}

zx_status_t TestLoopDispatcher::DispatchNextWait() {
    zx_port_packet_t packet;
    zx_status_t status = port_.wait(zx::time(0), &packet, 0);
    if (status != ZX_OK) {
        return status;
    }
    async_wait_t* wait = reinterpret_cast<async_wait_t*>(packet.key);
    list_delete(WaitToNode(wait));

    // Invoke the handler. Note that it might destroy itself.
    wait->handler(this, wait, status, &packet.signal);
    return ZX_OK;
}

void TestLoopDispatcher::DispatchTasks() {
    zx::time dispatch_time = *current_time_;

    // Dequeue and dispatch one task at a time in case an earlier task wants
    // to cancel a later task which has also come due.
    list_node_t* node;
    while ((node = list_peek_head(&task_list_))) {
        async_task_t* task = NodeToTask(node);
        if (task->deadline > current_time_->get()) {
            break;
        }
        list_delete(node);

        // Invoke the handler. Note that it might destroy itself.
        task->handler(this, task, ZX_OK);
    }

    // The following check fails when a task captures the TestLoop and advances
    // time. For one thing, this prevents the prospect of an infinte run.
    ZX_ASSERT(dispatch_time == *current_time_);
}

void TestLoopDispatcher::Shutdown() {
    list_node_t* node;
    while ((node = list_remove_head(&wait_list_))) {
        async_wait_t* wait = NodeToWait(node);
        wait->handler(this, wait, ZX_ERR_CANCELED, NULL);
    }
    while ((node = list_remove_head(&task_list_))) {
        async_task_t* task = NodeToTask(node);
        task->handler(this, task, ZX_ERR_CANCELED);
    }
}

} // namespace async
