/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */
#include <autoconf.h>
#include <sel4serialserver/gen_config.h>

#include <stdio.h>
#include <string.h>

#include <sel4/sel4.h>
#include <vka/vka.h>
#include <vka/object.h>
#include <vka/capops.h>

#include <utils/arith.h>
#include <utils/ansi.h>
#include <sel4utils/api.h>
#include <sel4utils/strerror.h>
#include <sel4platsupport/platsupport.h>

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

/* Define global instance. */
static serial_server_context_t serial_server;

static char *colors[] = {
    ANSI_COLOR(RED),
    ANSI_COLOR(GREEN),
    ANSI_COLOR(YELLOW),
    ANSI_COLOR(BLUE),
    ANSI_COLOR(MAGENTA),
    ANSI_COLOR(CYAN),

    ANSI_COLOR(RED, BOLD),
    ANSI_COLOR(GREEN, BOLD),
    ANSI_COLOR(YELLOW, BOLD),
    ANSI_COLOR(BLUE, BOLD),
    ANSI_COLOR(MAGENTA, BOLD),
    ANSI_COLOR(CYAN, BOLD),

    ANSI_COLOR(RED, ITALIC),
    ANSI_COLOR(GREEN, ITALIC),
    ANSI_COLOR(YELLOW, ITALIC),
    ANSI_COLOR(BLUE, ITALIC),
    ANSI_COLOR(MAGENTA, ITALIC),
    ANSI_COLOR(CYAN, ITALIC),

    ANSI_COLOR(RED, UNDERLINE),
    ANSI_COLOR(GREEN, UNDERLINE),
    ANSI_COLOR(YELLOW, UNDERLINE),
    ANSI_COLOR(BLUE, UNDERLINE),
    ANSI_COLOR(MAGENTA, UNDERLINE),
    ANSI_COLOR(CYAN, UNDERLINE),
};

#define NUM_COLORS ARRAY_SIZE(colors)
#define BADGE_TO_COLOR(badge) (colors[(badge) % NUM_COLORS])

serial_server_context_t *get_serial_server(void)
{
    return &serial_server;
}

static inline seL4_MessageInfo_t recv(seL4_Word *sender_badge)
{
    return api_recv(get_serial_server()->server_ep_obj.cptr, sender_badge, get_serial_server()->server_thread.reply.cptr);
}

static inline void reply(seL4_MessageInfo_t tag)
{
    api_reply(get_serial_server()->server_thread.reply.cptr, tag);
}

serial_server_registry_entry_t *serial_server_registry_get_entry_by_badge(seL4_Word badge_value)
{
    if (badge_value == SERIAL_SERVER_BADGE_VALUE_EMPTY
        || get_serial_server()->registry == NULL
        || badge_value > get_serial_server()->registry_n_entries) {
        return NULL;
    }
    /* If the badge value has been released, return NULL. */
    if (get_serial_server()->registry[badge_value - 1].badge_value
        == SERIAL_SERVER_BADGE_VALUE_EMPTY) {
        return NULL;
    }

    return &get_serial_server()->registry[badge_value - 1];
}

bool serial_server_badge_is_allocated(seL4_Word badge_value)
{
    serial_server_registry_entry_t *tmp;

    tmp = serial_server_registry_get_entry_by_badge(badge_value);
    if (tmp == NULL) {
        return false;
    }

    return tmp->badge_value != SERIAL_SERVER_BADGE_VALUE_EMPTY;
}

seL4_Word serial_server_badge_value_get_unused(void)
{
    if (get_serial_server()->registry == NULL) {
        return SERIAL_SERVER_BADGE_VALUE_EMPTY;
    }

    for (int i = 0; i < get_serial_server()->registry_n_entries; i++) {
        if (get_serial_server()->registry[i].badge_value != SERIAL_SERVER_BADGE_VALUE_EMPTY) {
            continue;
        }

        /* Badge value 0 will never be allocated, so index 0 is actually
         * badge 1, and index 1 is badge 2, and so on ad infinitum.
         */
        get_serial_server()->registry[i].badge_value = i + 1;
        return get_serial_server()->registry[i].badge_value;
    }

    return SERIAL_SERVER_BADGE_VALUE_EMPTY;
}

seL4_Word serial_server_badge_value_alloc(void)
{
    serial_server_registry_entry_t *tmp;
    seL4_Word ret;

    ret = serial_server_badge_value_get_unused();
    if (ret != SERIAL_SERVER_BADGE_VALUE_EMPTY) {
        /* Success */
        return ret;
    }

    tmp = realloc(get_serial_server()->registry,
                  sizeof(*get_serial_server()->registry)
                  * (get_serial_server()->registry_n_entries + 1));
    if (tmp == NULL) {
        ZF_LOGD(SERSERVS"badge_value_alloc: Failed resize pool.");
        return SERIAL_SERVER_BADGE_VALUE_EMPTY;
    }

    get_serial_server()->registry = tmp;
    get_serial_server()->registry[get_serial_server()->registry_n_entries].badge_value =
        SERIAL_SERVER_BADGE_VALUE_EMPTY;
    get_serial_server()->registry_n_entries++;

    /* If it fails again (some other caller raced us and got the new ID before
     * we did) that's tough luck -- the caller should probably look into
     * serializing the calls.
     */
    return serial_server_badge_value_get_unused();
}

void serial_server_badge_value_free(seL4_Word badge_value)
{
    serial_server_registry_entry_t *tmp;

    if (badge_value == SERIAL_SERVER_BADGE_VALUE_EMPTY) {
        return;
    }

    tmp = serial_server_registry_get_entry_by_badge(badge_value);
    if (tmp == NULL) {
        return;
    }

    tmp->badge_value = SERIAL_SERVER_BADGE_VALUE_EMPTY;
}

static void serial_server_registry_insert(seL4_Word badge_value, void *shmem,
                                          seL4_CPtr *shmem_frame_caps,
                                          size_t shmem_size)
{
    serial_server_registry_entry_t *tmp;

    tmp = serial_server_registry_get_entry_by_badge(badge_value);
    /* If this is NULL, something went very wrong, because this function is only
     * called after the server checks to ensure that the badge value has been
     * allocated in the registry. Technically, this should never happen, but
     * an assert doesn't hurt.
     */
    assert(tmp != NULL);

    tmp->badge_value = badge_value;
    tmp->shmem = shmem;
    tmp->shmem_size = shmem_size;
    tmp->shmem_frame_caps = shmem_frame_caps;
}

static void serial_server_registry_remove(seL4_Word badge_value)
{
    serial_server_registry_entry_t *tmp;

    tmp = serial_server_registry_get_entry_by_badge(badge_value);
    if (tmp == NULL) {
        return;
    }
    serial_server_badge_value_free(badge_value);
}

static void serial_server_set_frame_recv_path(void)
{
    seL4_SetCapReceivePath(get_serial_server()->server_cspace,
                           get_serial_server()->frame_cap_recv_cspaths[0].capPtr,
                           get_serial_server()->frame_cap_recv_cspaths[0].capDepth);
}

/** Processes all FUNC_CONNECT_REQ IPC messages. Establishes
 * shared mem mappings with new clients and sets up book-keeping metadata.
 *
 * Clients calling connect() will pass us a list of Frame caps which we must
 * map in order to establish shared mem with those clients. In this function,
 * the library maps the client's frames into the server's VSpace.
 */
seL4_Error serial_server_func_connect(seL4_MessageInfo_t tag,
                                      seL4_Word client_badge_value,
                                      size_t client_shmem_size)
{
    seL4_Error error;
    size_t client_shmem_n_pages;
    void *shmem_tmp = NULL;
    seL4_CPtr *client_frame_caps = NULL;
    cspacepath_t client_frame_cspath_tmp;

    if (client_shmem_size == 0) {
        ZF_LOGW(SERSERVS"connect: Invalid shared mem window size of 0B.\n");
        return seL4_InvalidArgument;
    }

    client_shmem_n_pages = BYTES_TO_4K_PAGES(client_shmem_size);
    /* The client should be allocated a badge value by the Parent, before it
     * attempts to connect to the Server.
     *
     * The reason being that when the badge is allocated, the metadata array
     * is resized as well, so badge allocation is also metadata allocation.
     */
    if (client_badge_value == SERIAL_SERVER_BADGE_VALUE_EMPTY
        || !serial_server_badge_is_allocated(client_badge_value)) {
        ZF_LOGW(SERSERVS"connect: Please allocate a badge value to this new "
                "client.\n");
        return -1;
    }
    /* Make sure that the client didn't request a shmem mapping larger than the
     * server is willing to handle.
     */
    if (client_shmem_n_pages > BYTES_TO_4K_PAGES(get_serial_server()->shmem_max_size)) {
        /* If the client asks for a shmem mapping too large, we refuse, and
         * send the value of shmem_max_size in SSMSGREG_RESPONSE
         * so it can try again.
         */
        ZF_LOGW(SERSERVS"connect: New client badge %x is asking to establish "
                "shmem mapping of %dB, but server max accepted shmem size is "
                "%dB.",
                client_badge_value, client_shmem_size,
                get_serial_server()->shmem_max_size);
        return SERIAL_SERVER_ERROR_SHMEM_TOO_LARGE;
    }

    if (seL4_MessageInfo_get_extraCaps(tag) != client_shmem_n_pages) {
        ZF_LOGW(SERSERVS"connect: Received %d Frame caps from client "
                "badge %x.\n\tbut client requested shmem mapping of %d "
                "frames. Possible cap transfer error.",
                seL4_MessageInfo_get_extraCaps(tag), client_badge_value,
                client_shmem_n_pages);
        return seL4_InvalidCapability;
    }

    /* Prepare an array of the client's shmem Frame caps to be mapped into our
     * VSpace.
     */
    client_frame_caps = calloc((client_shmem_n_pages + 1), sizeof(seL4_CPtr));
    if (client_frame_caps == NULL) {
        ZF_LOGE(SERSERVS"connect: Failed to alloc frame cap list for client "
                "shmem.");
        return seL4_NotEnoughMemory;
    }
    for (size_t i = 0; i < client_shmem_n_pages; i++) {
        /* For each frame, we need to make an seL4_CNode_Copy of it before
         * we zero-out the receive slots, or else when we delete the receive
         * slots, the frames will be revoked and unmapped.
         */
        error = vka_cspace_alloc_path(get_serial_server()->server_vka,
                                      &client_frame_cspath_tmp);
        if (error != 0) {
            ZF_LOGE(SERSERVS"connect: Failed to alloc CSpace slot for frame "
                    "%zd of %zd received from client badge %lx.",
                    i + 1, client_shmem_n_pages, (long)client_badge_value);
            goto out;
        }

        /* Copy the frame cap from the recv slot to the perm slot now. */
        error = vka_cnode_move(&client_frame_cspath_tmp,
                               &get_serial_server()->frame_cap_recv_cspaths[i]);
        if (error != 0) {
            ZF_LOGE(SERSERVS"connect: Failed to move %zuth frame-cap received "
                    " from client badge %lx.", i + 1, (long)client_badge_value);
            goto out;
        }

        client_frame_caps[i] = client_frame_cspath_tmp.capPtr;
        ZF_LOGD("connect: moved received client Frame cap %d from recv slot %"PRIxPTR" to slot %"PRIxPTR".",
                i + 1, get_serial_server()->frame_cap_recv_cspaths[i].capPtr,
                client_frame_caps[i]);
    }

    /* Map the frames into the vspace. */
    shmem_tmp = vspace_map_pages(get_serial_server()->server_vspace, client_frame_caps,
                                 NULL,
                                 seL4_AllRights, client_shmem_n_pages,
                                 seL4_PageBits,
                                 true);
    if (shmem_tmp == NULL) {
        ZF_LOGE(SERSERVS"connect: Failed to map shmem.");
        error = seL4_NotEnoughMemory;
        goto out;
    }

    serial_server_registry_insert(client_badge_value, shmem_tmp,
                                  client_frame_caps, client_shmem_size);

    ZF_LOGI(SERSERVS"connect: New client: badge %x, shmem %p, %d pages.",
            client_badge_value, shmem_tmp, client_shmem_n_pages);

    return seL4_NoError;

out:
    if (shmem_tmp != NULL) {
        vspace_unmap_pages(get_serial_server()->server_vspace, shmem_tmp,
                           client_shmem_n_pages, seL4_PageBits,
                           VSPACE_PRESERVE);
    }

    if (client_frame_caps != NULL) {
        for (size_t i = 0; i < client_shmem_n_pages; i++) {
            /* Because client_frame_caps was alloc'd with calloc, we can depend on
             * the unused slots being filled with 0s. Break on first unallocated.
             */
            if (client_frame_caps[i] == 0) {
                break;
            }
            client_frame_cspath_tmp.capPtr = client_frame_caps[i];
            vka_cspace_free_path(get_serial_server()->server_vka,
                                 client_frame_cspath_tmp);
        }
    }

    free(client_frame_caps);
    return error;
}

static int serial_server_func_write(serial_server_registry_entry_t *client_data,
                                    size_t message_len, size_t *bytes_written)
{
    *bytes_written = 0;

    if (client_data == NULL || bytes_written == NULL) {
        ZF_LOGE(SERSERVS"printf: Got NULL for required argument.");
        return seL4_InvalidArgument;
    }
    if (message_len > client_data->shmem_size) {
        return seL4_RangeError;
    }

    /* Write out */
    if (config_set(CONFIG_SERIAL_SERVER_COLOURED_OUTPUT)) {
        printf("%s", COLOR_RESET);
        printf("%s", BADGE_TO_COLOR(client_data->badge_value));
    }
    fwrite((void *)client_data->shmem, message_len, 1, stdout);
    if (config_set(CONFIG_SERIAL_SERVER_COLOURED_OUTPUT)) {
        printf("%s", COLOR_RESET);
    }
    *bytes_written = message_len;
    return 0;
}

static void serial_server_func_disconnect(serial_server_registry_entry_t *client_data)
{
    /* Tear down shmem and release the badge value for reuse. */
    vspace_unmap_pages(get_serial_server()->server_vspace,
                       (void *)client_data->shmem,
                       BYTES_TO_4K_PAGES(client_data->shmem_size),
                       seL4_PageBits, get_serial_server()->server_vka);
    free(client_data->shmem_frame_caps);
    serial_server_registry_remove(client_data->badge_value);
}

static void serial_server_func_kill(void)
{
    /* Tear down all existing connections. */
    for (int i = 0; i < get_serial_server()->registry_n_entries; i++) {
        serial_server_registry_entry_t *curr = &get_serial_server()->registry[i];

        if (curr->badge_value == SERIAL_SERVER_BADGE_VALUE_EMPTY
            || BYTES_TO_4K_PAGES(curr->shmem_size) == 0) {
            continue;
        }

        serial_server_func_disconnect(&get_serial_server()->registry[i]);
    }
}

/** Debugging function -- prints out the state of the registry and the server's
 * current list of clients.
 *
 * Can either print shallow or deep.
 * @param dump_frame_caps If true, print the array of frames caps that underlie
 *                        the shared mem mapping to each client.
 */
void serial_server_registry_dump(bool dump_frame_caps)
{
    serial_server_registry_entry_t *tmp;

    if (get_serial_server()->registry == NULL) {
        ZF_LOGD("Registry is NULL.");
    }
    for (int i = 0; i < get_serial_server()->registry_n_entries; i++) {
        tmp = &get_serial_server()->registry[i];
        ZF_LOGD("Reg: idx %d, badge %d, shmem_size %d, shmem %p, caps %p.",
                i, tmp->badge_value, tmp->shmem_size, tmp->shmem,
                tmp->shmem_frame_caps);

        if (!dump_frame_caps) {
            continue;
        }

        for (int j = 0; j < BYTES_TO_4K_PAGES(tmp->shmem_size); j++) {
            ZF_LOGD("Reg badge %d: frame cap %d: %"PRIxPTR".",
                    tmp->badge_value, j + 1, tmp->shmem_frame_caps[j]);
        }
    }
}

void serial_server_main(void)
{
    seL4_MessageInfo_t tag;
    seL4_Word sender_badge;
    enum serial_server_funcs func;
    int keep_going = 1;
    UNUSED seL4_Error error;
    serial_server_registry_entry_t *client_data = NULL;
    size_t buff_len, bytes_written;

    /* Bind to the serial driver. */
    error = platsupport_serial_setup_simple(get_serial_server()->server_vspace,
                                            get_serial_server()->server_simple,
                                            get_serial_server()->server_vka);
    if (error != 0) {
        ZF_LOGE(SERSERVS"main: Failed to bind to serial.");
    } else {
        ZF_LOGI(SERSERVS"main: Bound to the serial driver.");
    }

    /* The Parent will seL4_Call() the us, the Server, right after spawning us.
     * It will expect us to seL4_Reply() with an error status code - we will
     * send this Reply regardless of the outcome of the platform serial bind
     * operation.
     *
     * First call seL4_Recv() to get the Reply cap back to the Parent, and then
     * seL4_Reply to report our status.
     */
    recv(&sender_badge);

    seL4_SetMR(SSMSGREG_FUNC, FUNC_SERVER_SPAWN_SYNC_ACK);
    tag = seL4_MessageInfo_new(error, 0, 0, SSMSGREG_SPAWN_SYNC_ACK_END);
    reply(tag);

    /* If the bind failed, this thread has essentially failed its mandate, so
     * there is no reason to leave it scheduled. Kill it (to whatever extent
     * that is possible).
     */
    if (error != 0) {
        seL4_TCB_Suspend(get_serial_server()->server_thread.tcb.cptr);
    }

    ZF_LOGI(SERSERVS"main: Entering main loop and accepting requests.");
    while (keep_going) {
        /* Set the CNode slots where caps from clients will go */
        serial_server_set_frame_recv_path();

        tag = recv(&sender_badge);
        ZF_LOGD(SERSERVS "main: Got message from %x", sender_badge);

        func = seL4_GetMR(SSMSGREG_FUNC);

        /* Lookup the registry entry for this sender to make sure that the sender
         * has a shmem buffer registered with us. If not, ignore the message.
         * New connection requests are of course, exempt from the requirement to
         * already have an established connection.
         */
        if (func != FUNC_CONNECT_REQ) {
            client_data = serial_server_registry_get_entry_by_badge(sender_badge);
            if (client_data == NULL) {
                ZF_LOGW(SERSERVS"main: Got message from unregistered client "
                        "badge %x. Ignoring.",
                        sender_badge);
                continue;
            }
        }

        switch (func) {
        case FUNC_CONNECT_REQ:
            ZF_LOGD(SERSERVS"main: Got connect request from client badge %x.",
                    sender_badge);
            error = serial_server_func_connect(tag,
                                               sender_badge,
                                               seL4_GetMR(SSMSGREG_CONNECT_REQ_SHMEM_SIZE));

            seL4_SetMR(SSMSGREG_FUNC, FUNC_CONNECT_ACK);
            seL4_SetMR(SSMSGREG_CONNECT_ACK_MAX_SHMEM_SIZE,
                       get_serial_server()->shmem_max_size);
            tag = seL4_MessageInfo_new(error, 0, 0, SSMSGREG_CONNECT_ACK_END);
            reply(tag);
            break;

        case FUNC_WRITE_REQ:
            /* The Server's ABI for the write() request is as follows:
             *
             * The server returns the number of bytes it actually wrote out to the
             * serial in a msg-reg (SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN),
             * aside from also returning an error code in the "label" of the header.
             *
             * This was done because attempting to overload the "label" of the
             * header to hold a value that can be either:
             *      (1) a negative integer error code, (2) a positive size_t
             *      byte length
             * Was not very clean especially since the bit-width of the "label"
             * field shouldn't be assumed lightly, so separating the error code
             * from the number of bytes written was the cleaner approach.
             *
             * At the client end, the client can decide to overload an ssize_t
             * to encode both types of values.
             */

            ZF_LOGD(SERSERVS"main: Got write request from client badge %x.",
                    sender_badge);
            buff_len = seL4_GetMR(SSMSGREG_WRITE_REQ_BUFF_LEN);
            error = serial_server_func_write(client_data, buff_len,
                                             &bytes_written);

            seL4_SetMR(SSMSGREG_FUNC, FUNC_WRITE_ACK);
            seL4_SetMR(SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN, bytes_written);
            tag = seL4_MessageInfo_new(error, 0, 0, SSMSGREG_WRITE_ACK_END);
            reply(tag);
            break;

        case FUNC_DISCONNECT_REQ:
            ZF_LOGD(SERSERVS"main: Got disconnect request from client badge %x.",
                    sender_badge);
            serial_server_func_disconnect(client_data);

            seL4_SetMR(SSMSGREG_FUNC, FUNC_DISCONNECT_ACK);
            tag = seL4_MessageInfo_new(error, 0, 0, SSMSGREG_DISCONNECT_ACK_END);
            reply(tag);
            break;

        case FUNC_KILL_REQ:
            ZF_LOGI(SERSERVS"main: Got KILL request from client badge %x.",
                    sender_badge);
            /* The actual contents of the Reply don't matter here. */
            seL4_SetMR(SSMSGREG_FUNC, FUNC_KILL_ACK);
            tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_KILL_ACK_END);
            reply(tag);
            /* Break out of the loop */
            keep_going = 0;
            break;

        default:
            ZF_LOGW(SERSERVS "main: Unknown function %d requested.", func);
            break;
        }
    }

    serial_server_func_kill();
    /* After we break out of the loop, seL4_TCB_Suspend ourselves */
    ZF_LOGI(SERSERVS"main: Suspending.");
    seL4_TCB_Suspend(get_serial_server()->server_thread.tcb.cptr);
}
