/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include <sel4/sel4.h>

#include <sel4utils/strerror.h>
#include <vka/vka.h>
#include <vka/capops.h>
#include <vka/object.h>
#include <vspace/vspace.h>

#include "serial_server.h"
#include <serial_server/client.h>

/** Single-call connection to the server thread, using the parent as a
 * proxy.
 *
 * Sends IPC to the parent thread, asking it to connect us to the server
 * thread. It does this by allocating some memory to be used as shmem, and then
 * sending a Frame cap to that memory, to the Parent, which then maps it into
 * the server.
 *
 * The Parent then replies by sending us an Endpoint cap which can be used to
 * communicate directly with the server thread from then on.
 */

int
serial_server_client_connect(seL4_CPtr badged_server_ep_cap,
                             vka_t *client_vka, vspace_t *client_vspace,
                             serial_client_context_t *conn)
{
    seL4_Error error;
    int shmem_n_pages;
    uintptr_t shmem_tmp_vaddr;
    seL4_MessageInfo_t tag;
    cspacepath_t frame_cspath;

    if (badged_server_ep_cap == 0 || client_vka == NULL || client_vspace == NULL
            || conn == NULL) {
        return seL4_InvalidArgument;
    }

    memset(conn, 0, sizeof(serial_client_context_t));

    shmem_n_pages = BYTES_TO_4K_PAGES(SERIAL_SERVER_SHMEM_MAX_SIZE);
    if (shmem_n_pages > seL4_MsgMaxExtraCaps) {
        ZF_LOGE(SERSERVC"connect: Currently unsupported shared memory size: "
                "IPC cap transfer capability is inadequate.");
        return seL4_RangeError;
    }
    conn->shmem = vspace_new_pages(client_vspace,
                                   seL4_AllRights,
                                   shmem_n_pages,
                                   seL4_PageBits);
    if (conn->shmem == NULL) {
        ZF_LOGE(SERSERVC"connect: Failed to alloc shmem.");
        return seL4_NotEnoughMemory;
    }
    assert(IS_ALIGNED((uintptr_t)conn->shmem, seL4_PageBits));

    /* Look up the Frame cap behind each page in the shmem range, and marshal
     * all of those Frame caps to the parent. The parent will then map those
     * Frames into its VSpace and establish a shmem link.
     */
    shmem_tmp_vaddr = (uintptr_t)conn->shmem;
    for (int i = 0; i < shmem_n_pages; i++) {
        vka_cspace_make_path(client_vka,
                             vspace_get_cap(client_vspace,
                                            (void *)shmem_tmp_vaddr),
                             &frame_cspath);

        seL4_SetCap(i, frame_cspath.capPtr);
        shmem_tmp_vaddr += BIT(seL4_PageBits);
    }

    /* Call the server asking it to establish the shmem mapping with us, and
     * get us connected up.
     */
    seL4_SetMR(SSMSGREG_FUNC, FUNC_CONNECT_REQ);
    seL4_SetMR(SSMSGREG_CONNECT_REQ_SHMEM_SIZE,
               SERIAL_SERVER_SHMEM_MAX_SIZE);
    /* extraCaps doubles up as the number of shmem pages. */
    tag = seL4_MessageInfo_new(0, 0,
                               shmem_n_pages,
                               SSMSGREG_CONNECT_REQ_END);

    tag = seL4_Call(badged_server_ep_cap, tag);

    /* It makes sense to verify that the message we're getting back is an
     * ACK response to our request message.
     */
    if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_CONNECT_ACK) {
        error = seL4_IllegalOperation;
        ZF_LOGE(SERSERVC"connect: Reply message was not a CONNECT_ACK as "
                "expected.");
        goto out;
    }
    /* When the parent replies, we check to see if it was successful, etc. */
    error = seL4_MessageInfo_get_label(tag);
    if (error != (int)SERIAL_SERVER_NOERROR) {
        ZF_LOGE(SERSERVC"connect ERR %d: Failed to connect to the server.",
                error);

        if (error == (int)SERIAL_SERVER_ERROR_SHMEM_TOO_LARGE) {
            ZF_LOGE(SERSERVC"connect: Your requested shmem mapping size is too "
                    "large.\n\tServer's max shmem size is %luB.",
                    (long)seL4_GetMR(SSMSGREG_CONNECT_ACK_MAX_SHMEM_SIZE));
        }
        goto out;
    }

    conn->shmem_size = SERIAL_SERVER_SHMEM_MAX_SIZE;
    vka_cspace_make_path(client_vka, badged_server_ep_cap,
                         &conn->badged_server_ep_cspath);

    return seL4_NoError;

out:
    if (conn->shmem != NULL) {
        vspace_unmap_pages(client_vspace, (void *)conn->shmem, shmem_n_pages,
                           seL4_PageBits, VSPACE_FREE);
    }
    return error;
}

/** Performs the IPC register setup for a write() call to the server.
 *
 * The Server's ABI for the write() request has changed a little: the server
 * now returns the number of bytes it wrote out to the serial in a msg-reg,
 * aside from also returning an error code in the "label" of the header.
 *
 * @param conn Initialized connection token returned by
 *             serial_server_client_connect().
 * @param len length of the data in the buffer.
 * @param server_nbytes_written The value the server reports that it actually
 *                              wrote to the serial device.
 * @return 0 on success, or integer error value on error.
 */
static ssize_t
serial_server_write_ipc_invoke(serial_client_context_t *conn, ssize_t len)
{
    seL4_MessageInfo_t tag;

    seL4_SetMR(SSMSGREG_FUNC, FUNC_WRITE_REQ);
    seL4_SetMR(SSMSGREG_WRITE_REQ_BUFF_LEN, len);
    tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_WRITE_REQ_END);

    tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag);

    if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_WRITE_ACK) {
        ZF_LOGE(SERSERVC"printf: Reply message was not a WRITE_ACK as "
                "expected.");
        return - seL4_IllegalOperation;
    }
    if (seL4_MessageInfo_get_label(tag) != 0) {
        return - seL4_MessageInfo_get_label(tag);
    }

    return seL4_GetMR(SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN);
}

ssize_t
serial_server_printf(serial_client_context_t *conn, const char *fmt, ...)
{
    ssize_t expanded_fmt_length;
    va_list args;

    /* We simplify everything by just vsnprintf()ing, instead of marshaling
     * a variable length format string and a variable length argument list.
     */
    if (fmt == NULL || conn == NULL || conn->shmem == NULL) {
        ZF_LOGE(SERSERVC"printf: NULL passed for required arguments.\n"
                "\tIs connection handle valid?");
        return -seL4_InvalidArgument;
    }

    va_start(args, fmt);
    expanded_fmt_length = vsnprintf((char *)conn->shmem, conn->shmem_size,
                                    fmt, args);
    va_end(args);
    if (expanded_fmt_length < 0) {
        return -1;
    }

    if ((size_t)expanded_fmt_length >= conn->shmem_size) {
        ZF_LOGE(SERSERVC"printf: This printf call's total expanded length (%zd) "
                "exceeds your %zd bytes shmem buffer.\n\tMessage not sent to "
                "server.",
                expanded_fmt_length,
                conn->shmem_size);
        return -seL4_RangeError;
    }

    /* Else, send it off to the server. */
    return serial_server_write_ipc_invoke(conn, expanded_fmt_length);
}

ssize_t serial_server_flush(serial_client_context_t *conn, ssize_t len)
{
    if (len > conn->shmem_size) {
        return -seL4_RangeError;
    }

    if (len == 0) {
        return 0;
    }

    return serial_server_write_ipc_invoke(conn, len);
}

ssize_t
serial_server_write(serial_client_context_t *conn, const char *in_buff, ssize_t len)
{
    if (in_buff == NULL || conn == NULL || conn->shmem == NULL) {
        ZF_LOGE(SERSERVC"printf: NULL passed for required arguments.\n"
                "\tIs connection handle valid?");
        return -seL4_InvalidArgument;
    }
    if (len > conn->shmem_size) {
        return -seL4_RangeError;
    }

    if (len == 0) {
        return 0;
    }

    memcpy((void *)conn->shmem, in_buff, len);

    /* Else, send it off to the server. */
    return serial_server_write_ipc_invoke(conn, len);
}

void
serial_server_disconnect(serial_client_context_t *conn)
{
    seL4_MessageInfo_t tag;

    if (conn == NULL) {
        return;
    }

    seL4_SetMR(SSMSGREG_FUNC, FUNC_DISCONNECT_REQ);
    tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_DISCONNECT_REQ_END);

    tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag);

    if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_DISCONNECT_ACK) {
        ZF_LOGE(SERSERVC"disconnect: reply message was not a DISCONNECT_ACK "
                "as expected.");
    }
}

int
serial_server_kill(serial_client_context_t *conn)
{
    seL4_MessageInfo_t tag;

    if (conn == NULL) {
        return seL4_InvalidArgument;
    }

    seL4_SetMR(SSMSGREG_FUNC, FUNC_KILL_REQ);
    tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_KILL_REQ_END);

    tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag);

    if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_KILL_ACK) {
        ZF_LOGE(SERSERVC"kill: Reply message was not a KILL_ACK as expected.");
        return seL4_IllegalOperation;
    }
    return seL4_MessageInfo_get_label(tag);
}
