/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#pragma once

#include <sys/types.h>
#include <stdint.h>

#include <sel4/sel4.h>

#include <simple/simple.h>
#include <sel4utils/thread.h>
#include <vka/vka.h>
#include <vka/object.h>
#include <vspace/vspace.h>

/** @file API for making requests to a serial server multiplexing thread.
 *
 * If CONFIG_SERIAL_SERVER_COLOURED_OUTPUT is set, the output will also
 * be wrapped in ansi escape codes which allow client code to be identified
 * in a terminal.
 *
 * By default, the new thread which is created by this API will share the
 * CSpace and VSpace of its creator. Each client of the server thread is required
 * to have a badged cap to the Endpoint that the Server is listening on. The
 * badge on this Endpoint cap must have been allocated by the library's
 * serial_server_badge_value_alloc() or serial_server_badge_value_get_unused()
 * function.
 *
 * Establishing a connection to the server is as simple as calling:
 *  serial_client_context_t conn;
 *  error = serial_server_client_connect(..., &conn).
 * Then check the error value returned:
 *  if (error != SERIAL_SERVER_NOERROR) { ... }
 *
 * If the connect() call was successful, make sure you save the
 * serial_client_context_t object. Then use the serial server's printf from
 * that point on, by passing the serial_client_context_t object:
 *  serial_server_printf(&conn, "Hello world from %s!", "john");
 *
 * You can easily abstract away the long function name using preprocessor
 * defines or wrapper functions such as:
 *  #define printf(fmt, ...) serial_server_printf(&global_client_conn, ## __VA_ARGS__)
 *
 * CAUTION:
 * All vka_t, vpsace_t, and simple_t instances passed to this library by
 * reference must remain functional throughout the lifetime of the server.
 */

/* Context given to each client to preserve state.
 *
 * This is an opaque handle data type, and clients are not to assume the
 * layout or purpose of its members.
 */
typedef struct _serial_client_context {
    seL4_Word badge_value;
    cspacepath_t badged_server_ep_cspath;
    volatile char *shmem;
    size_t shmem_size;
} serial_client_context_t;

/** Establishes a connection to the server thread and returns a connection
 * handle. It is expected that this will be called by the client thread itself.
 *
 * CAUTION:
 * All vka_t, vpsace_t, and simple_t instances passed to this library by
 * reference must remain functional throughout the lifetime of the server.
 *
 * Can be called by any thread which has an endpoint to the thread/process
 * that spawned the server thread.
 * @param server_ep_cap CPtr to an endpoint between the client and the SERVER
 *                      thread.
 * @param client_vka Initialized vka_t for the client thread.
 * @param client_vspace Initialized vspace_t for the client thread.
 * @param client_badge_value Unique badge value for the connection between this
 *                           client and the server thread. Each client of the
 *                           server must have a unique badge value. Two clients
 *                           connecting with the same badge value will cause the
 *                           server to overwrite the former with the latter.
 * @param conn [out] Connection token returned by the library. Use this to make calls
 *             to the server thread.
 * @return Error value: 0 on success, non-zero on failure.
 */
int serial_server_client_connect(seL4_CPtr server_ep_cap,
                                 vka_t *client_vka,
                                 vspace_t *client_vspace,
                                 serial_client_context_t *conn);

/** Sends a request to the server to print a message to the serial.
 *
 * @param ctxt Valid connection token returned by serial_server_client_connect().
 * @param fmt Valid printf format specifier string.
 * @param ... Variadic argument list for printf.
 * @return The number of characters printed. If the call had to be aborted due
 *         to an error condition, a negative error code is returned.
 */
ssize_t serial_server_printf(serial_client_context_t *ctxt, const char *fmt, ...);


/** Sends the server a request to print the current contents of the shared memory buffer.
 *  For use when the client uses the shared memory buffer directly.
 *
 * @param ctxt Valid connection token returned by serial_server_client_connect().
 * @param len the size of the buffer data.
 * @return The number of bytes written (positive integer), or a negative integer
 *         for error condition.
 *
 */
ssize_t serial_server_flush(serial_client_context_t *ctxt, ssize_t len);

/** Sends a request to the server to write a fixed-length buffer to the serial.
 *
 * @param ctxt Valid connection token returned by serial_server_client_connect().
 * @param in_buff Input buffer of data.
 * @param len the size of the buffer data.
 * @return The number of bytes written (positive integer), or a negative integer
 *         for error condition.
 */
ssize_t serial_server_write(serial_client_context_t *ctxt, const char *in_buff, ssize_t len);

/** Sends a request to the server to disconnect the calling client.
 *
 * Causes the server to release the connection metadata it holds about the
 * client in question and teardown the shared memory mapping between the server
 * and that client.
 * @param ctxt Initialized connection token returned from
 *             serial_server_client_connect().
 */
void serial_server_disconnect(serial_client_context_t *ctxt);

/** Sends a request to the server to "kill" itself.
 *
 * In practice, right now that means that the server exits its message loop and
 * stops listening for IPC from clients, and then seL4_TCB_Suspend()s itself.
 * @param conn Connection handle to the server, returned by
 *             serial_server_client_connect().
 * @return Integer value: 0 on successfull "kill", non-zero if the server was
 *         unable to shutdown for some reason.
 */
int serial_server_kill(serial_client_context_t *conn);
