/*
 * Copyright (c) 2021, Google Inc. All rights reserved
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <assert.h>
#include <err.h>
#include <interface/metrics/consumer.h>
#include <kernel/mutex.h>
#include <lib/dpc.h>
#include <lib/trusty/handle.h>
#include <lib/trusty/ipc.h>
#include <lib/trusty/ipc_msg.h>
#include <lib/trusty/trusty_app.h>
#include <lk/init.h>
#include <lk/trace.h>
#include <string.h>
#include <trusty/uuid.h>

#define LOCAL_TRACE (0)

/*
 * Format of the payload is "<UUID>:<app name>", with neither UUID nor app name
 * being null-terminated. However, unlike APP_NAME_MAX_SIZE, UUID_STR_SIZE
 * counts the null character. Hence, the maximum size of an app name is
 * METRICS_MAX_APP_ID_LEN - UUID_STR_SIZE.
 */
static_assert(UUID_STR_SIZE <= METRICS_MAX_APP_ID_LEN);
#define APP_NAME_MAX_SIZE (METRICS_MAX_APP_ID_LEN - UUID_STR_SIZE)

/**
 * enum chan_state - states of the metrics consumer channel event handler
 * CHAN_STATE_WAITING_CHAN_READY:
 *      Inital state of the channel handler. At this point we are waiting for an
 *      IPC_HANDLE_POLL_READY channel event that signifies that metrics consumer
 *      connection is ready for use. After consuming this event, we transition
 *      to %CHAN_STATE_IDLE state.
 * CHAN_STATE_IDLE:
 *      While in this state we (2) can not consume any events from the channel
 *      (1) can only send one message over the channel. Once a message is sent,
 *      we transition to either %CHAN_STATE_WAITING_CRASH_RESP or
 *      %CHAN_STATE_WAITING_EVENT_DROP_RESP depending on what message was sent.
 * CHAN_STATE_WAITING_CRASH_RESP:
 *      In this state we are waiting for a response to a message about an app
 *      crash.  After receiving the response message, we transition to
 *      %CHAN_STATE_IDLE state.
 * CHAN_STATE_WAITING_EVENT_DROP_RESP:
 *      In this state we are waiting for a response to a message about an event
 *      drop. After receiving the response message, we transition to
 *      %CHAN_STATE_IDLE state.
 */
enum chan_state {
    CHAN_STATE_WAITING_CHAN_READY = 0,
    CHAN_STATE_IDLE = 1,
    CHAN_STATE_WAITING_CRASH_RESP = 2,
    CHAN_STATE_WAITING_EVENT_DROP_RESP = 3,
};

struct metrics_ctx {
    struct handle* chan;
    enum chan_state chan_state;
    bool event_dropped;
};

static struct metrics_ctx ctx;
static mutex_t ctx_lock = MUTEX_INITIAL_VALUE(ctx_lock);

static int recv_resp(struct handle* chan, uint32_t cmd) {
    int rc;
    struct ipc_msg_info msg_info;
    struct metrics_resp resp;

    rc = ipc_get_msg(chan, &msg_info);
    if (rc != NO_ERROR) {
        TRACEF("failed (%d) to get message\n", rc);
        return rc;
    }

    struct iovec_kern iov = {
            .iov_base = &resp,
            .iov_len = sizeof(resp),
    };
    struct ipc_msg_kern ipc_msg = {
            .num_iov = 1,
            .iov = &iov,
            .num_handles = 0,
            .handles = NULL,
    };
    rc = ipc_read_msg(chan, msg_info.id, 0, &ipc_msg);
    ipc_put_msg(chan, msg_info.id);

    if (rc < 0) {
        TRACEF("failed (%d) ipc_read_msg().\n", rc);
        return rc;
    }

    if (rc != sizeof(resp)) {
        TRACEF("unexpected number of bytes received: %d.\n", rc);
        return ERR_BAD_LEN;
    }

    if (resp.cmd != (cmd | METRICS_CMD_RESP_BIT)) {
        TRACEF("unknown command received: %u.\n", resp.cmd);
        return ERR_CMD_UNKNOWN;
    }

    if (resp.status != METRICS_NO_ERROR) {
        TRACEF("event report failure: %d.\n", resp.status);
        /* This error is not severe enough to close the connection. */
    }

    return NO_ERROR;
}

static int send_req(struct handle* chan,
                    struct ipc_msg_kern* ipc_msg,
                    size_t total_len) {
    int rc = ipc_send_msg(chan, ipc_msg);
    if (rc < 0) {
        TRACEF("failed (%d) to send message\n", rc);
        return rc;
    }

    if (rc != (int)total_len) {
        TRACEF("unexpected number of bytes sent: %d\n", rc);
        return ERR_BAD_LEN;
    }

    return NO_ERROR;
}

static int report_crash(struct handle* chan,
                        struct trusty_app* app,
                        uint32_t crash_reason) {
    int rc;
    struct metrics_req req = {};
    struct metrics_report_crash_req args = {};
    size_t total_len;

    DEBUG_ASSERT(is_mutex_held(&ctx_lock));

    uuid_to_str(&app->props.uuid, args.app_id);

    req.cmd = METRICS_CMD_REPORT_CRASH;
    args.crash_reason = crash_reason;

    struct iovec_kern iovs[] = {
            {
                    .iov_base = &req,
                    .iov_len = sizeof(req),
            },
            {
                    .iov_base = &args,
                    .iov_len = sizeof(args),
            },
    };
    struct ipc_msg_kern ipc_msg = {
            .num_iov = countof(iovs),
            .iov = iovs,
    };

    total_len = sizeof(req) + sizeof(args);
    rc = send_req(chan, &ipc_msg, total_len);
    if (rc != NO_ERROR) {
        TRACEF("failed (%d) report app crash\n", rc);
        return rc;
    }

    return NO_ERROR;
}

static int report_event_drop(struct handle* chan) {
    int rc;
    struct metrics_req req;

    DEBUG_ASSERT(is_mutex_held(&ctx_lock));

    req.cmd = METRICS_CMD_REPORT_EVENT_DROP;
    req.reserved = 0;

    struct iovec_kern iov = {
            .iov_base = &req,
            .iov_len = sizeof(req),
    };
    struct ipc_msg_kern ipc_msg = {
            .num_iov = 1,
            .iov = &iov,
    };

    rc = send_req(chan, &ipc_msg, sizeof(req));
    if (rc != NO_ERROR) {
        TRACEF("failed (%d) report event drop\n", rc);
        return rc;
    }

    return NO_ERROR;
}

static int on_ta_crash(struct trusty_app* app, uint32_t reason) {
    int rc;

    mutex_acquire(&ctx_lock);

    if (ctx.chan_state != CHAN_STATE_IDLE) {
        TRACEF("there is a metrics event still in progress or metrics TA "
               "is unavailable\n");
        ctx.event_dropped = true;
        goto out;
    }

    if (!ctx.chan) {
        TRACEF("failed get metrics consumer channel\n");
        goto out;
    }

    rc = report_crash(ctx.chan, app, reason);
    if (rc != NO_ERROR) {
        TRACEF("failed (%d) report app crash\n", rc);
        goto err;
    }

    ctx.chan_state = CHAN_STATE_WAITING_CRASH_RESP;
    goto out;

err:
    handle_close(ctx.chan);
    ctx.chan = NULL;
out:
    mutex_release(&ctx_lock);
    /*
     * Returning an error here will bring down the kernel. Metrics reporting
     * isn't critical. So, we always return NO_ERROR. If something goes wrong,
     * printing an error should suffice.
     */
    return NO_ERROR;
}

static struct trusty_app_notifier notifier = {
        .crash = on_ta_crash,
};

static void handle_chan(struct dpc* work) {
    int rc;
    uint32_t event;

    mutex_acquire(&ctx_lock);

    event = ctx.chan->ops->poll(ctx.chan, ~0U, true);
    if (event & IPC_HANDLE_POLL_HUP) {
        TRACEF("received IPC_HANDLE_POLL_HUP, closing channel\n");
        goto err;
    }

    switch (ctx.chan_state) {
    case CHAN_STATE_WAITING_CHAN_READY:
        if (!(event & IPC_HANDLE_POLL_READY)) {
            TRACEF("unexpected channel event: 0x%x\n", event);
            goto err;
        }

        ctx.chan_state = CHAN_STATE_IDLE;
        goto out;

    case CHAN_STATE_IDLE:
        TRACEF("unexpected channel event: 0x%x\n", event);
        goto err;

    case CHAN_STATE_WAITING_CRASH_RESP:
        if (!(event & IPC_HANDLE_POLL_MSG)) {
            TRACEF("unexpected channel event: 0x%x\n", event);
            goto err;
        }

        rc = recv_resp(ctx.chan, METRICS_CMD_REPORT_CRASH);
        if (rc != NO_ERROR) {
            TRACEF("failed (%d) receive response\n", rc);
            goto err;
        }

        ctx.chan_state = CHAN_STATE_IDLE;

        if (ctx.event_dropped) {
            rc = report_event_drop(ctx.chan);
            if (rc != NO_ERROR) {
                TRACEF("failed (%d) report event drop\n", rc);
                goto err;
            }
            ctx.chan_state = CHAN_STATE_WAITING_EVENT_DROP_RESP;
            goto out;
        }

        goto out;

    case CHAN_STATE_WAITING_EVENT_DROP_RESP:
        if (!(event & IPC_HANDLE_POLL_MSG)) {
            TRACEF("unexpected channel event: 0x%x\n", event);
            goto err;
        }

        rc = recv_resp(ctx.chan, METRICS_CMD_REPORT_EVENT_DROP);
        if (rc != NO_ERROR) {
            TRACEF("failed (%d) receive response\n", rc);
            goto err;
        }

        ctx.chan_state = CHAN_STATE_IDLE;
        ctx.event_dropped = false;
        goto out;
    }

err:
    handle_close(ctx.chan);
    ctx.chan = NULL;
out:
    mutex_release(&ctx_lock);
}

static struct dpc chan_event_work = {
        .node = LIST_INITIAL_CLEARED_VALUE,
        .cb = handle_chan,
};

static void on_handle_event(struct handle_waiter* waiter) {
    int rc = dpc_enqueue_work(NULL, &chan_event_work, false);
    if (rc != NO_ERROR) {
        TRACEF("failed (%d) to enqueue dpc work\n", rc);
    }
}

static struct handle_waiter waiter = {
        .node = LIST_INITIAL_CLEARED_VALUE,
        .notify_proc = on_handle_event,
};

static void metrics_init(uint level) {
    int rc = ipc_port_connect_async(&kernel_uuid, METRICS_CONSUMER_PORT,
                                    IPC_PORT_PATH_MAX,
                                    IPC_CONNECT_WAIT_FOR_PORT, &ctx.chan);
    if (rc) {
        TRACEF("failed (%d) to connect to port\n", rc);
        goto err_port_connect;
    }

    rc = trusty_register_app_notifier(&notifier);
    if (rc) {
        TRACEF("failed (%d) to register app notifier\n", rc);
        goto err_app_notifier;
    }

    ctx.chan_state = CHAN_STATE_WAITING_CHAN_READY;
    handle_add_waiter(ctx.chan, &waiter);

    return;

err_app_notifier:
    handle_close(ctx.chan);
    ctx.chan = NULL;
err_port_connect:
    return;
}

/* Need to init before (LK_INIT_LEVEL_APPS - 1) to register an app notifier. */
LK_INIT_HOOK(metrics, metrics_init, LK_INIT_LEVEL_APPS - 2);
