/*
 * QEMU monitor
 *
 * Copyright (c) 2003-2004 Fabrice Bellard
 *
 * 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 "qemu/osdep.h"

#include "chardev/char-io.h"
#include "monitor-internal.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-control.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qlist.h"
#include "trace.h"

/*
 * qmp_dispatcher_co_busy is used for synchronisation between the
 * monitor thread and the main thread to ensure that the dispatcher
 * coroutine never gets scheduled a second time when it's already
 * scheduled (scheduling the same coroutine twice is forbidden).
 *
 * It is true if the coroutine will process at least one more request
 * before going to sleep.  Either it has been kicked already, or it
 * is active and processing requests.  Additional requests may therefore
 * be pushed onto mon->qmp_requests, and @qmp_dispatcher_co_shutdown may
 * be set without further ado.  @qmp_dispatcher_co must not be woken up
 * in this case.
 *
 * If false, you have to wake up @qmp_dispatcher_co after pushing new
 * requests. You also have to set @qmp_dispatcher_co_busy to true
 * before waking up the coroutine.
 *
 * The coroutine will automatically change this variable back to false
 * before it yields.  Nobody else may set the variable to false.
 *
 * Access must be atomic for thread safety.
 */
static bool qmp_dispatcher_co_busy = true;

struct QMPRequest {
    /* Owner of the request */
    MonitorQMP *mon;
    /*
     * Request object to be handled or Error to be reported
     * (exactly one of them is non-null)
     */
    QObject *req;
    Error *err;
};
typedef struct QMPRequest QMPRequest;

QmpCommandList qmp_commands, qmp_cap_negotiation_commands;

static bool qmp_oob_enabled(MonitorQMP *mon)
{
    return mon->capab[QMP_CAPABILITY_OOB];
}

static void monitor_qmp_caps_reset(MonitorQMP *mon)
{
    memset(mon->capab_offered, 0, sizeof(mon->capab_offered));
    memset(mon->capab, 0, sizeof(mon->capab));
    mon->capab_offered[QMP_CAPABILITY_OOB] = mon->common.use_io_thread;
}

static void qmp_request_free(QMPRequest *req)
{
    qobject_unref(req->req);
    error_free(req->err);
    g_free(req);
}

/* Caller must hold mon->qmp.qmp_queue_lock */
static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon)
{
    while (!g_queue_is_empty(mon->qmp_requests)) {
        qmp_request_free(g_queue_pop_head(mon->qmp_requests));
    }
}

static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon)
{
    QEMU_LOCK_GUARD(&mon->qmp_queue_lock);

    /*
     * Same condition as in monitor_qmp_dispatcher_co(), but before
     * removing an element from the queue (hence no `- 1`).
     * Also, the queue should not be empty either, otherwise the
     * monitor hasn't been suspended yet (or was already resumed).
     */
    bool need_resume = (!qmp_oob_enabled(mon) ||
        mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX)
        && !g_queue_is_empty(mon->qmp_requests);

    monitor_qmp_cleanup_req_queue_locked(mon);

    if (need_resume) {
        /*
         * handle_qmp_command() suspended the monitor because the
         * request queue filled up, to be resumed when the queue has
         * space again.  We just emptied it; resume the monitor.
         *
         * Without this, the monitor would remain suspended forever
         * when we get here while the monitor is suspended.  An
         * unfortunately timed CHR_EVENT_CLOSED can do the trick.
         */
        monitor_resume(&mon->common);
    }

}

void qmp_send_response(MonitorQMP *mon, const QDict *rsp)
{
    const QObject *data = QOBJECT(rsp);
    GString *json;

    json = qobject_to_json_pretty(data, mon->pretty);
    assert(json != NULL);
    trace_monitor_qmp_respond(mon, json->str);

    g_string_append_c(json, '\n');
    monitor_puts(&mon->common, json->str);

    g_string_free(json, true);
}

/*
 * Emit QMP response @rsp to @mon.
 * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP.
 * Nothing is emitted then.
 */
static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp)
{
    if (rsp) {
        qmp_send_response(mon, rsp);
    }
}

/*
 * Runs outside of coroutine context for OOB commands, but in
 * coroutine context for everything else.
 */
static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
{
    QDict *rsp;
    QDict *error;

    rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon),
                       &mon->common);

    if (mon->commands == &qmp_cap_negotiation_commands) {
        error = qdict_get_qdict(rsp, "error");
        if (error
            && !g_strcmp0(qdict_get_try_str(error, "class"),
                    QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND))) {
            /* Provide a more useful error message */
            qdict_del(error, "desc");
            qdict_put_str(error, "desc", "Expecting capabilities negotiation"
                          " with 'qmp_capabilities'");
        }
    }

    monitor_qmp_respond(mon, rsp);
    qobject_unref(rsp);
}

/*
 * Pop a QMP request from a monitor request queue.
 * Return the request, or NULL all request queues are empty.
 * We are using round-robin fashion to pop the request, to avoid
 * processing commands only on a very busy monitor.  To achieve that,
 * when we process one request on a specific monitor, we put that
 * monitor to the end of mon_list queue.
 *
 * Note: if the function returned with non-NULL, then the caller will
 * be with qmp_mon->qmp_queue_lock held, and the caller is responsible
 * to release it.
 */
static QMPRequest *monitor_qmp_requests_pop_any_with_lock(void)
{
    QMPRequest *req_obj = NULL;
    Monitor *mon;
    MonitorQMP *qmp_mon;

    QTAILQ_FOREACH(mon, &mon_list, entry) {
        if (!monitor_is_qmp(mon)) {
            continue;
        }

        qmp_mon = container_of(mon, MonitorQMP, common);
        qemu_mutex_lock(&qmp_mon->qmp_queue_lock);
        req_obj = g_queue_pop_head(qmp_mon->qmp_requests);
        if (req_obj) {
            /* With the lock of corresponding queue held */
            break;
        }
        qemu_mutex_unlock(&qmp_mon->qmp_queue_lock);
    }

    if (req_obj) {
        /*
         * We found one request on the monitor. Degrade this monitor's
         * priority to lowest by re-inserting it to end of queue.
         */
        QTAILQ_REMOVE(&mon_list, mon, entry);
        QTAILQ_INSERT_TAIL(&mon_list, mon, entry);
    }

    return req_obj;
}

static QMPRequest *monitor_qmp_dispatcher_pop_any(void)
{
    while (true) {
        /*
         * To avoid double scheduling, busy is true on entry to
         * monitor_qmp_dispatcher_co(), and must be set again before
         * aio_co_wake()-ing it.
         */
        assert(qatomic_read(&qmp_dispatcher_co_busy) == true);

        /*
         * Mark the dispatcher as not busy already here so that we
         * don't miss any new requests coming in the middle of our
         * processing.
         *
         * Clear qmp_dispatcher_co_busy before reading request.
         */
        qatomic_set_mb(&qmp_dispatcher_co_busy, false);

        WITH_QEMU_LOCK_GUARD(&monitor_lock) {
            QMPRequest *req_obj;

            /* On shutdown, don't take any more requests from the queue */
            if (qmp_dispatcher_co_shutdown) {
                return NULL;
            }

            req_obj = monitor_qmp_requests_pop_any_with_lock();
            if (req_obj) {
                return req_obj;
            }
        }

        /*
         * No more requests to process.  Wait to be reentered from
         * handle_qmp_command() when it pushes more requests, or
         * from monitor_cleanup() when it requests shutdown.
         */
        qemu_coroutine_yield();
    }
}

void coroutine_fn monitor_qmp_dispatcher_co(void *data)
{
    QMPRequest *req_obj;
    QDict *rsp;
    bool oob_enabled;
    MonitorQMP *mon;

    while ((req_obj = monitor_qmp_dispatcher_pop_any()) != NULL) {
        trace_monitor_qmp_in_band_dequeue(req_obj,
                                          req_obj->mon->qmp_requests->length);

        /*
         * @req_obj has a request, we hold req_obj->mon->qmp_queue_lock
         */

        mon = req_obj->mon;

        /*
         * We need to resume the monitor if handle_qmp_command()
         * suspended it.  Two cases:
         * 1. OOB enabled: mon->qmp_requests has no more space
         *    Resume right away, so that OOB commands can get executed while
         *    this request is being processed.
         * 2. OOB disabled: always
         *    Resume only after we're done processing the request,
         * We need to save qmp_oob_enabled() for later, because
         * qmp_qmp_capabilities() can change it.
         */
        oob_enabled = qmp_oob_enabled(mon);
        if (oob_enabled
            && mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
            monitor_resume(&mon->common);
        }

        /*
         * Drop the queue mutex now, before yielding, otherwise we might
         * deadlock if the main thread tries to lock it.
         */
        qemu_mutex_unlock(&mon->qmp_queue_lock);

        if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
            /*
             * Someone rescheduled us (probably because a new requests
             * came in), but we didn't actually yield. Do that now,
             * only to be immediately reentered and removed from the
             * list of scheduled coroutines.
             */
            qemu_coroutine_yield();
        }

        /* Process request */
        if (req_obj->req) {
            if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {
                QDict *qdict = qobject_to(QDict, req_obj->req);
                QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
                GString *id_json;

                id_json = id ? qobject_to_json(id) : g_string_new(NULL);
                trace_monitor_qmp_cmd_in_band(id_json->str);
                g_string_free(id_json, true);
            }
            monitor_qmp_dispatch(mon, req_obj->req);
        } else {
            assert(req_obj->err);
            trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err));
            rsp = qmp_error_response(req_obj->err);
            req_obj->err = NULL;
            monitor_qmp_respond(mon, rsp);
            qobject_unref(rsp);
        }

        if (!oob_enabled) {
            monitor_resume(&mon->common);
        }

        qmp_request_free(req_obj);
    }
    qatomic_set(&qmp_dispatcher_co, NULL);
}

void qmp_dispatcher_co_wake(void)
{
    /* Write request before reading qmp_dispatcher_co_busy.  */
    smp_mb__before_rmw();

    if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
        aio_co_wake(qmp_dispatcher_co);
    }
}

static void handle_qmp_command(void *opaque, QObject *req, Error *err)
{
    MonitorQMP *mon = opaque;
    QDict *qdict = qobject_to(QDict, req);
    QMPRequest *req_obj;

    assert(!req != !err);

    if (req && trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
        GString *req_json = qobject_to_json(req);
        trace_handle_qmp_command(mon, req_json->str);
        g_string_free(req_json, true);
    }

    if (qdict && qmp_is_oob(qdict)) {
        /* OOB commands are executed immediately */
        if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_OUT_OF_BAND)) {
            QObject *id = qdict_get(qdict, "id");
            GString *id_json;

            id_json = id ? qobject_to_json(id) : g_string_new(NULL);
            trace_monitor_qmp_cmd_out_of_band(id_json->str);
            g_string_free(id_json, true);
        }
        monitor_qmp_dispatch(mon, req);
        qobject_unref(req);
        return;
    }

    req_obj = g_new0(QMPRequest, 1);
    req_obj->mon = mon;
    req_obj->req = req;
    req_obj->err = err;

    /* Protect qmp_requests and fetching its length. */
    WITH_QEMU_LOCK_GUARD(&mon->qmp_queue_lock) {

        /*
         * Suspend the monitor when we can't queue more requests after
         * this one.  Dequeuing in monitor_qmp_dispatcher_co() or
         * monitor_qmp_cleanup_queue_and_resume() will resume it.
         * Note that when OOB is disabled, we queue at most one command,
         * for backward compatibility.
         */
        if (!qmp_oob_enabled(mon) ||
            mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
            monitor_suspend(&mon->common);
        }

        /*
         * Put the request to the end of queue so that requests will be
         * handled in time order.  Ownership for req_obj, req,
         * etc. will be delivered to the handler side.
         */
        trace_monitor_qmp_in_band_enqueue(req_obj, mon,
                                          mon->qmp_requests->length);
        assert(mon->qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX);
        g_queue_push_tail(mon->qmp_requests, req_obj);
    }

    /* Kick the dispatcher routine */
    qmp_dispatcher_co_wake();
}

static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
{
    MonitorQMP *mon = opaque;

    json_message_parser_feed(&mon->parser, (const char *) buf, size);
}

static QDict *qmp_greeting(MonitorQMP *mon)
{
    QList *cap_list = qlist_new();
    QObject *ver = NULL;
    QDict *args;
    QMPCapability cap;

    args = qdict_new();
    qmp_marshal_query_version(args, &ver, NULL);
    qobject_unref(args);

    for (cap = 0; cap < QMP_CAPABILITY__MAX; cap++) {
        if (mon->capab_offered[cap]) {
            qlist_append_str(cap_list, QMPCapability_str(cap));
        }
    }

    return qdict_from_jsonf_nofail(
        "{'QMP': {'version': %p, 'capabilities': %p}}",
        ver, cap_list);
}

static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
{
    QDict *data;
    MonitorQMP *mon = opaque;

    switch (event) {
    case CHR_EVENT_OPENED:
        mon->commands = &qmp_cap_negotiation_commands;
        monitor_qmp_caps_reset(mon);
        data = qmp_greeting(mon);
        qmp_send_response(mon, data);
        qobject_unref(data);
        mon_refcount++;
        break;
    case CHR_EVENT_CLOSED:
        /*
         * Note: this is only useful when the output of the chardev
         * backend is still open.  For example, when the backend is
         * stdio, it's possible that stdout is still open when stdin
         * is closed.
         */
        monitor_qmp_cleanup_queue_and_resume(mon);
        json_message_parser_destroy(&mon->parser);
        json_message_parser_init(&mon->parser, handle_qmp_command,
                                 mon, NULL);
        mon_refcount--;
        monitor_fdsets_cleanup();
        break;
    case CHR_EVENT_BREAK:
    case CHR_EVENT_MUX_IN:
    case CHR_EVENT_MUX_OUT:
        /* Ignore */
        break;
    }
}

void monitor_data_destroy_qmp(MonitorQMP *mon)
{
    json_message_parser_destroy(&mon->parser);
    qemu_mutex_destroy(&mon->qmp_queue_lock);
    monitor_qmp_cleanup_req_queue_locked(mon);
    g_queue_free(mon->qmp_requests);
}

static void monitor_qmp_setup_handlers_bh(void *opaque)
{
    MonitorQMP *mon = opaque;
    GMainContext *context;

    assert(mon->common.use_io_thread);
    context = iothread_get_g_main_context(mon_iothread);
    assert(context);
    qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
                             monitor_qmp_read, monitor_qmp_event,
                             NULL, &mon->common, context, true);
    monitor_list_append(&mon->common);
}

void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
{
    MonitorQMP *mon = g_new0(MonitorQMP, 1);

    if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
        g_free(mon);
        return;
    }
    qemu_chr_fe_set_echo(&mon->common.chr, true);

    /* Note: we run QMP monitor in I/O thread when @chr supports that */
    monitor_data_init(&mon->common, true, false,
                      qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));

    mon->pretty = pretty;

    qemu_mutex_init(&mon->qmp_queue_lock);
    mon->qmp_requests = g_queue_new();

    json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
    if (mon->common.use_io_thread) {
        /*
         * Make sure the old iowatch is gone.  It's possible when
         * e.g. the chardev is in client mode, with wait=on.
         */
        remove_fd_in_watch(chr);
        /*
         * We can't call qemu_chr_fe_set_handlers() directly here
         * since chardev might be running in the monitor I/O
         * thread.  Schedule a bottom half.
         */
        aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
                                monitor_qmp_setup_handlers_bh, mon);
        /* The bottom half will add @mon to @mon_list */
    } else {
        qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
                                 monitor_qmp_read, monitor_qmp_event,
                                 NULL, &mon->common, NULL, true);
        monitor_list_append(&mon->common);
    }
}
