/*
 * Copyright 2019, 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 <sel4nanopb/sel4nanopb.h>
#include <sel4rpc/server.h>
#include <sel4utils/api.h>
#include <simple/simple.h>
#include <vka/vka.h>
#include <vka/object.h>
#include <vka/capops.h>
#include <rpc.pb.h>
#include <pb_encode.h>
#include <pb_decode.h>

#include <utils/zf_log.h>

static int sel4rpc_handle_memory(sel4rpc_server_env_t *env, RpcMessage *rpcMsg)
{
    cspacepath_t path;
    int error;
    if (rpcMsg->msg.memory.action == Action_ALLOCATE) {
        error = vka_cspace_alloc_path(env->vka, &path);
        if (error) {
            ZF_LOGE("Failed to alloc path: %d\n", error);
            sel4rpc_server_reply(env, 0, 1, 0);
            return -1;
        }

        uintptr_t cookie;
        error = vka_utspace_alloc_at(env->vka, &path, rpcMsg->msg.memory.type, rpcMsg->msg.memory.size_bits,
                                     rpcMsg->msg.memory.address, &cookie);
        if (error) {
            ZF_LOGE("Failed to alloc at: %d\n", error);
            vka_cspace_free_path(env->vka, path);
            sel4rpc_server_reply(env, 0, 1, 0);
            return -1;
        }

        seL4_SetCap(0, path.capPtr);
        int ret = sel4rpc_server_reply(env, 1, 0, cookie);

        vka_cnode_delete(&path);
        vka_cspace_free_path(env->vka, path);

        return ret;
    } else {
        vka_utspace_free(env->vka, rpcMsg->msg.memory.type, rpcMsg->msg.memory.size_bits,
                         rpcMsg->msg.memory.address);

        return sel4rpc_server_reply(env, 0, 0, 0);
    }
}

static int sel4rpc_handle_ioport(sel4rpc_server_env_t *env, RpcMessage *rpcMsg)
{
    cspacepath_t path;
    int error;
    error = vka_cspace_alloc_path(env->vka, &path);
    if (error) {
        ZF_LOGE("Failed to alloc path: %d\n", error);
        sel4rpc_server_reply(env, 0, 1, 0);
        return -1;
    }

    seL4_Error err = simple_get_IOPort_cap(env->simple, rpcMsg->msg.ioport.start, rpcMsg->msg.ioport.end,
                                           path.root, path.capPtr, path.capDepth);
    if (err != seL4_NoError) {
        vka_cspace_free_path(env->vka, path);
        sel4rpc_server_reply(env, 0, 1, 0);
        return err;
    }

    seL4_SetCap(0, path.capPtr);
    int ret = sel4rpc_server_reply(env, 1, 0, 0);

    vka_cnode_delete(&path);
    vka_cspace_free_path(env->vka, path);
    return ret;
}

static int sel4rpc_handle_irq(sel4rpc_server_env_t *env, RpcMessage *rpcMsg)
{
    cspacepath_t path;
    int error;
    error = vka_cspace_alloc_path(env->vka, &path);
    if (error) {
        ZF_LOGE("Failed to alloc path: %d\n", error);
        sel4rpc_server_reply(env, 0, 1, 0);
        return -1;
    }

    seL4_Error err = seL4_InvalidArgument;
    switch (rpcMsg->msg.irq.which_type) {
    case IrqAllocMessage_msi_tag: {
        /* x86 MSI IRQ */
#ifdef CONFIG_ARCH_X86
        IrqAllocMessagex86_MSI *msi = &rpcMsg->msg.irq.type.msi;
        err = arch_simple_get_msi(&env->simple->arch_simple, path, msi->pci_bus,
                                  msi->pci_dev, msi->pci_func, msi->handle, msi->vector);
#endif
        break;
    }
    case IrqAllocMessage_ioapic_tag: {
        /* x86 IOAPIC IRQ */
#ifdef CONFIG_ARCH_X86
        IrqAllocMessagex86_IOAPIC *ioapic = &rpcMsg->msg.irq.type.ioapic;
        err = arch_simple_get_ioapic(&env->simple->arch_simple, path, ioapic->ioapic,
                                     ioapic->pin, ioapic->level, ioapic->polarity, ioapic->vector);
#endif
        break;
    }
    case IrqAllocMessage_simple_tag: {
        /* Simple IRQ */
        IrqAllocMessageSimple *simple = &rpcMsg->msg.irq.type.simple;
#ifdef CONFIG_ARCH_ARM
        if (simple->setTrigger) {
            err = arch_simple_get_IRQ_trigger(&env->simple->arch_simple, simple->irq,
                                              simple->trigger, path);
        } else
#endif
        {
            err = simple_get_IRQ_handler(env->simple, simple->irq, path);
        }
        break;
    }
    default:
        ZF_LOGE("Unknown IRQ type");
        vka_cspace_free_path(env->vka, path);
        return -1;
    }

    if (err != seL4_NoError) {
        vka_cspace_free_path(env->vka, path);
        sel4rpc_server_reply(env, 0, 1, 0);
        return err;
    }

    seL4_SetCap(0, path.capPtr);
    int ret = sel4rpc_server_reply(env, 1, 0, 0);

    vka_cnode_delete(&path);
    vka_cspace_free_path(env->vka, path);
    return ret;
}

int sel4rpc_default_handler(sel4rpc_server_env_t *env, UNUSED void *data, RpcMessage *rpcMsg)
{
    cspacepath_t path;
    path.capPtr = seL4_CapNull;
    switch (rpcMsg->which_msg) {
    case RpcMessage_memory_tag:
        return sel4rpc_handle_memory(env, rpcMsg);
    case RpcMessage_ioport_tag:
        return sel4rpc_handle_ioport(env, rpcMsg);
    case RpcMessage_irq_tag:
        return sel4rpc_handle_irq(env, rpcMsg);
    default:
        ZF_LOGE("Not sure what to do!");
    }

    return -1;
}

int sel4rpc_server_init(sel4rpc_server_env_t *env, vka_t *vka,
                        sel4rpc_handler_t handler_func, void *data, vka_object_t *reply, simple_t *simple)
{
    env->vka = vka;
    env->reply = reply;
    env->handler = handler_func;
    env->data = data;
    env->simple = simple;
    return 0;
}

int sel4rpc_server_reply(sel4rpc_server_env_t *env, int caps, int errorCode, int cookie)
{
    pb_ostream_t ostream = pb_ostream_from_IPC(0);
    RpcMessage rpcMsg;
    rpcMsg.which_msg = RpcMessage_ret_tag;
    rpcMsg.msg.ret.errorCode = errorCode;
    rpcMsg.msg.ret.cookie = cookie;

    bool ret = pb_encode_delimited(&ostream, &RpcMessage_msg, &rpcMsg);
    if (!ret) {
        /* encode failed, clean up any caps */
        while (caps > 0) {
            caps--;
            vka_cspace_free(env->vka, seL4_GetCap(caps));
        }
        ZF_LOGE("Failed to encode reply (%s)", PB_GET_ERROR(&ostream));
        return -1;
    }

    size_t size = ostream.bytes_written / sizeof(seL4_Word);
    if (ostream.bytes_written % sizeof(seL4_Word)) {
        size++;
    }

    api_reply(env->reply->cptr, seL4_MessageInfo_new(0, 0, caps, size));

    return 0;
}

int sel4rpc_server_recv(sel4rpc_server_env_t *env)
{
    RpcMessage rpcMsg;
    pb_istream_t stream = pb_istream_from_IPC(1);
    bool ret = pb_decode_delimited(&stream, &RpcMessage_msg, &rpcMsg);
    if (!ret) {
        ZF_LOGE("Invalid protobuf stream (%s)", PB_GET_ERROR(&stream));
        return -1;
    }

    int err = 0;
    if (env->handler) {
        err = env->handler(env, env->data, &rpcMsg);
    } else {
        err = sel4rpc_default_handler(env, NULL, &rpcMsg);
    }
    return err;
}
