// 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 <fuchsia/ldsvc/c/fidl.h>
#include <string.h>
#include <threads.h>
#include <zircon/fidl.h>
#include <zircon/syscalls.h>

#include <unittest/unittest.h>

static bool g_server_done = false;

static zx_status_t ldsvc_Done(void* ctx) {
    g_server_done = true;
    return ZX_OK;
}

static zx_status_t ldsvc_LoadObject(void* ctx, const char* object_name_data, size_t object_name_size, fidl_txn_t* txn) {
    size_t len = strlen("object name");
    ASSERT_EQ(len, object_name_size, "");
    EXPECT_EQ(0, memcmp(object_name_data, "object name", len), "");
    zx_handle_t event = ZX_HANDLE_INVALID;
    EXPECT_EQ(ZX_OK, zx_event_create(0, &event), "");
    return fuchsia_ldsvc_LoaderLoadObject_reply(txn, 42, event);
}

static zx_status_t ldsvc_LoadScriptInterpreter(void* ctx, const char* interpreter_name_data, size_t interpreter_name_size, fidl_txn_t* txn) {
    size_t len = strlen("script interpreter");
    ASSERT_EQ(len, interpreter_name_size, "");
    EXPECT_EQ(0, memcmp(interpreter_name_data, "script interpreter", len), "");
    zx_handle_t event = ZX_HANDLE_INVALID;
    EXPECT_EQ(ZX_OK, zx_event_create(0, &event), "");
    return fuchsia_ldsvc_LoaderLoadScriptInterpreter_reply(txn, 43, event);
}

static zx_status_t ldsvc_Config(void* ctx, const char* config_data, size_t config_size, fidl_txn_t* txn) {
    size_t len = strlen("my config");
    ASSERT_EQ(len, config_size, "");
    EXPECT_EQ(0, memcmp(config_data, "my config", len), "");
    return fuchsia_ldsvc_LoaderConfig_reply(txn, 44);
}

static zx_status_t ldsvc_Clone(void* ctx, zx_handle_t loader, fidl_txn_t* txn) {
    EXPECT_EQ(ZX_OK, zx_handle_close(loader), "");
    return fuchsia_ldsvc_LoaderClone_reply(txn, 45);
}

static zx_status_t ldsvc_DebugPublishDataSink(void* ctx, const char* data_sink_data, size_t data_sink_size, zx_handle_t data, fidl_txn_t* txn) {
    size_t len = strlen("my data sink");
    ASSERT_EQ(len, data_sink_size, "");
    EXPECT_EQ(0, memcmp(data_sink_data, "my data sink", len), "");
    EXPECT_EQ(ZX_OK, zx_handle_close(data), "");
    return fuchsia_ldsvc_LoaderDebugPublishDataSink_reply(txn, 46);
}

static zx_status_t ldsvc_DebugLoadConfig(void* ctx, const char* config_name_data, size_t config_name_size, fidl_txn_t* txn) {
    size_t len = strlen("my debug config");
    ASSERT_EQ(len, config_name_size, "");
    EXPECT_EQ(0, memcmp(config_name_data, "my debug config", len), "");
    zx_handle_t event = ZX_HANDLE_INVALID;
    EXPECT_EQ(ZX_OK, zx_event_create(0, &event), "");
    return fuchsia_ldsvc_LoaderDebugLoadConfig_reply(txn, 47, event);
}

static const fuchsia_ldsvc_Loader_ops_t kOps = {
    .Done = ldsvc_Done,
    .LoadObject = ldsvc_LoadObject,
    .LoadScriptInterpreter = ldsvc_LoadScriptInterpreter,
    .Config = ldsvc_Config,
    .Clone = ldsvc_Clone,
    .DebugPublishDataSink = ldsvc_DebugPublishDataSink,
    .DebugLoadConfig = ldsvc_DebugLoadConfig,
};

typedef struct ldsvc_connection {
    fidl_txn_t txn;
    zx_handle_t channel;
    zx_txid_t txid;
    uint32_t reply_count;
} ldsvc_connection_t;

static zx_status_t ldsvc_server_reply(fidl_txn_t* txn, const fidl_msg_t* msg) {
    ldsvc_connection_t* conn = (ldsvc_connection_t*)txn;
    if (msg->num_bytes < sizeof(fidl_message_header_t))
        return ZX_ERR_INVALID_ARGS;
    fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;
    hdr->txid = conn->txid;
    conn->txid = 0;
    ++conn->reply_count;
    return zx_channel_write(conn->channel, 0, msg->bytes, msg->num_bytes,
                            msg->handles, msg->num_handles);
}

static int ldsvc_server(void* ctx) {
    ldsvc_connection_t conn = {
        .txn.reply = ldsvc_server_reply,
        .channel = *(zx_handle_t*)ctx,
        .reply_count = 0u,
    };
    zx_status_t status = ZX_OK;
    g_server_done = false;

    while (status == ZX_OK && !g_server_done) {
        zx_signals_t observed;
        status = zx_object_wait_one(
            conn.channel, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
            ZX_TIME_INFINITE, &observed);
        if ((observed & ZX_CHANNEL_READABLE) != 0) {
            ASSERT_EQ(ZX_OK, status, "");
            char bytes[ZX_CHANNEL_MAX_MSG_BYTES];
            zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
            fidl_msg_t msg = {
                .bytes = bytes,
                .handles = handles,
                .num_bytes = 0u,
                .num_handles = 0u,
            };
            status = zx_channel_read(conn.channel, 0, bytes, handles,
                                     ZX_CHANNEL_MAX_MSG_BYTES,
                                     ZX_CHANNEL_MAX_MSG_HANDLES,
                                     &msg.num_bytes, &msg.num_handles);
            ASSERT_EQ(ZX_OK, status, "");
            ASSERT_GE(msg.num_bytes, sizeof(fidl_message_header_t), "");
            fidl_message_header_t* hdr = (fidl_message_header_t*)msg.bytes;
            conn.txid = hdr->txid;
            conn.reply_count = 0u;
            status = fuchsia_ldsvc_Loader_dispatch(NULL, &conn.txn, &msg, &kOps);
            ASSERT_EQ(ZX_OK, status, "");
            if (!g_server_done)
                ASSERT_EQ(1u, conn.reply_count, "");
        } else {
            break;
        }
    }

    zx_handle_close(conn.channel);
    return 0;
}

static bool loader_test(void) {
    BEGIN_TEST;

    zx_handle_t client, server;
    zx_status_t status = zx_channel_create(0, &client, &server);
    ASSERT_EQ(ZX_OK, status, "");

    thrd_t thread;
    int rv = thrd_create(&thread, ldsvc_server, &server);
    ASSERT_EQ(thrd_success, rv, "");

    {
        const char* object_name = "object name";
        zx_status_t rv = ZX_OK;
        zx_handle_t object = ZX_HANDLE_INVALID;
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderLoadObject(client, object_name, strlen(object_name), &rv, &object), "");
        ASSERT_EQ(42, rv, "");
        ASSERT_EQ(ZX_OK, zx_handle_close(object), "");
    }

    {
        const char* interpreter_name = "script interpreter";
        zx_status_t rv = ZX_OK;
        zx_handle_t object = ZX_HANDLE_INVALID;
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderLoadScriptInterpreter(client, interpreter_name, strlen(interpreter_name), &rv, &object), "");
        ASSERT_EQ(43, rv, "");
        ASSERT_EQ(ZX_OK, zx_handle_close(object), "");
    }

    {
        const char* config = "my config";
        zx_status_t rv = ZX_OK;
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderConfig(client, config, strlen(config), &rv), "");
        ASSERT_EQ(44, rv, "");
    }

    {
        zx_status_t rv = ZX_OK;
        zx_handle_t h1, h2;
        ASSERT_EQ(ZX_OK, zx_eventpair_create(0, &h1, &h2), "");
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderClone(client, h1, &rv), "");
        ASSERT_EQ(45, rv, "");
        ASSERT_EQ(ZX_ERR_PEER_CLOSED, zx_object_signal_peer(h2, 0, 0), "");
        ASSERT_EQ(ZX_OK, zx_handle_close(h2), "");
    }

    {
        const char* sink = "my data sink";
        zx_status_t rv = ZX_OK;
        zx_handle_t h1, h2;
        ASSERT_EQ(ZX_OK, zx_eventpair_create(0, &h1, &h2), "");
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderDebugPublishDataSink(client, sink, strlen(sink), h1, &rv), "");
        ASSERT_EQ(46, rv, "");
        ASSERT_EQ(ZX_ERR_PEER_CLOSED, zx_object_signal_peer(h2, 0, 0), "");
        ASSERT_EQ(ZX_OK, zx_handle_close(h2), "");
    }

    {
        const char* config_name = "my debug config";
        zx_status_t rv = ZX_OK;
        zx_handle_t object = ZX_HANDLE_INVALID;
        ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderDebugLoadConfig(client, config_name, strlen(config_name), &rv, &object), "");
        ASSERT_EQ(47, rv, "");
        ASSERT_EQ(ZX_OK, zx_handle_close(object), "");
    }

    ASSERT_EQ(ZX_OK, fuchsia_ldsvc_LoaderDone(client), "");
    ASSERT_EQ(ZX_OK, zx_handle_close(client), "");

    int result = 0;
    rv = thrd_join(thread, &result);
    ASSERT_EQ(thrd_success, rv, "");

    END_TEST;
}

BEGIN_TEST_CASE(ldsvc_tests)
RUN_NAMED_TEST("fuchsia.ldsvc.Loader test", loader_test)
END_TEST_CASE(ldsvc_tests);
