/*
 * Core Definitions for QAPI/QMP Dispatch
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu/osdep.h"

#include "qemu/aio.h"
#include "qapi/compat-policy.h"
#include "qapi/error.h"
#include "qapi/qmp-registry.h"
#include "qobject/qdict.h"
#include "qobject/qjson.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qobject-output-visitor.h"
#include "qobject/qbool.h"
#include "qemu/coroutine.h"
#include "qemu/main-loop.h"

Visitor *qobject_input_visitor_new_qmp(QObject *obj)
{
    Visitor *v = qobject_input_visitor_new(obj);

    visit_set_policy(v, &compat_policy);
    return v;
}

Visitor *qobject_output_visitor_new_qmp(QObject **result)
{
    Visitor *v = qobject_output_visitor_new(result);

    visit_set_policy(v, &compat_policy);
    return v;
}

static QDict *qmp_dispatch_check_obj(QDict *dict, bool allow_oob,
                                     Error **errp)
{
    const char *exec_key = NULL;
    const QDictEntry *ent;
    const char *arg_name;
    const QObject *arg_obj;

    for (ent = qdict_first(dict); ent;
         ent = qdict_next(dict, ent)) {
        arg_name = qdict_entry_key(ent);
        arg_obj = qdict_entry_value(ent);

        if (!strcmp(arg_name, "execute")
            || (!strcmp(arg_name, "exec-oob") && allow_oob)) {
            if (qobject_type(arg_obj) != QTYPE_QSTRING) {
                error_setg(errp, "QMP input member '%s' must be a string",
                           arg_name);
                return NULL;
            }
            if (exec_key) {
                error_setg(errp, "QMP input member '%s' clashes with '%s'",
                           arg_name, exec_key);
                return NULL;
            }
            exec_key = arg_name;
        } else if (!strcmp(arg_name, "arguments")) {
            if (qobject_type(arg_obj) != QTYPE_QDICT) {
                error_setg(errp,
                           "QMP input member 'arguments' must be an object");
                return NULL;
            }
        } else if (!strcmp(arg_name, "id")) {
            continue;
        } else {
            error_setg(errp, "QMP input member '%s' is unexpected",
                       arg_name);
            return NULL;
        }
    }

    if (!exec_key) {
        error_setg(errp, "QMP input lacks member 'execute'");
        return NULL;
    }

    return dict;
}

QDict *qmp_error_response(Error *err)
{
    QDict *rsp;

    rsp = qdict_from_jsonf_nofail("{ 'error': { 'class': %s, 'desc': %s } }",
                                  QapiErrorClass_str(error_get_class(err)),
                                  error_get_pretty(err));
    error_free(err);
    return rsp;
}

/*
 * Does @qdict look like a command to be run out-of-band?
 */
bool qmp_is_oob(const QDict *dict)
{
    return qdict_haskey(dict, "exec-oob")
        && !qdict_haskey(dict, "execute");
}

typedef struct QmpDispatchBH {
    const QmpCommand *cmd;
    Monitor *cur_mon;
    QDict *args;
    QObject **ret;
    Error **errp;
    Coroutine *co;
} QmpDispatchBH;

static void do_qmp_dispatch_bh(void *opaque)
{
    QmpDispatchBH *data = opaque;

    assert(monitor_cur() == NULL);
    monitor_set_cur(qemu_coroutine_self(), data->cur_mon);
    data->cmd->fn(data->args, data->ret, data->errp);
    monitor_set_cur(qemu_coroutine_self(), NULL);
    aio_co_wake(data->co);
}

/*
 * Runs outside of coroutine context for OOB commands, but in coroutine
 * context for everything else.
 */
QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *request,
                                       bool allow_oob, Monitor *cur_mon)
{
    Error *err = NULL;
    bool oob;
    const char *command;
    QDict *args;
    const QmpCommand *cmd;
    QDict *dict;
    QObject *id;
    QObject *ret = NULL;
    QDict *rsp = NULL;

    dict = qobject_to(QDict, request);
    if (!dict) {
        id = NULL;
        error_setg(&err, "QMP input must be a JSON object");
        goto out;
    }

    id = qdict_get(dict, "id");

    if (!qmp_dispatch_check_obj(dict, allow_oob, &err)) {
        goto out;
    }

    command = qdict_get_try_str(dict, "execute");
    oob = false;
    if (!command) {
        assert(allow_oob);
        command = qdict_get_str(dict, "exec-oob");
        oob = true;
    }
    cmd = qmp_find_command(cmds, command);
    if (cmd == NULL) {
        error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
                  "The command %s has not been found", command);
        goto out;
    }
    if (!compat_policy_input_ok(cmd->features, &compat_policy,
                                ERROR_CLASS_COMMAND_NOT_FOUND,
                                "command", command, &err)) {
        goto out;
    }
    if (!cmd->enabled) {
        error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
                  "Command %s has been disabled%s%s",
                  command,
                  cmd->disable_reason ? ": " : "",
                  cmd->disable_reason ?: "");
        goto out;
    }
    if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
        error_setg(&err, "The command %s does not support OOB",
                   command);
        goto out;
    }

    if (!qmp_command_available(cmd, &err)) {
        goto out;
    }

    if (!qdict_haskey(dict, "arguments")) {
        args = qdict_new();
    } else {
        args = qdict_get_qdict(dict, "arguments");
        qobject_ref(args);
    }

    assert(!(oob && qemu_in_coroutine()));
    assert(monitor_cur() == NULL);
    if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) {
        if (qemu_in_coroutine()) {
            /*
             * Move the coroutine from iohandler_ctx to qemu_aio_context for
             * executing the command handler so that it can make progress if it
             * involves an AIO_WAIT_WHILE().
             */
            aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self());
            qemu_coroutine_yield();
        }

        monitor_set_cur(qemu_coroutine_self(), cur_mon);
        cmd->fn(args, &ret, &err);
        monitor_set_cur(qemu_coroutine_self(), NULL);

        if (qemu_in_coroutine()) {
            /*
             * Yield and reschedule so the main loop stays responsive.
             *
             * Move back to iohandler_ctx so that nested event loops for
             * qemu_aio_context don't start new monitor commands.
             */
            aio_co_schedule(iohandler_get_aio_context(),
                            qemu_coroutine_self());
            qemu_coroutine_yield();
        }
    } else {
       /*
        * Actual context doesn't match the one the command needs.
        *
        * Case 1: we are in coroutine context, but command does not
        * have QCO_COROUTINE.  We need to drop out of coroutine
        * context for executing it.
        *
        * Case 2: we are outside coroutine context, but command has
        * QCO_COROUTINE.  Can't actually happen, because we get here
        * outside coroutine context only when executing a command
        * out of band, and OOB commands never have QCO_COROUTINE.
        */
        assert(!oob && qemu_in_coroutine() && !(cmd->options & QCO_COROUTINE));

        QmpDispatchBH data = {
            .cur_mon    = cur_mon,
            .cmd        = cmd,
            .args       = args,
            .ret        = &ret,
            .errp       = &err,
            .co         = qemu_coroutine_self(),
        };
        aio_bh_schedule_oneshot(iohandler_get_aio_context(), do_qmp_dispatch_bh,
                                &data);
        qemu_coroutine_yield();
    }
    qobject_unref(args);
    if (err) {
        /* or assert(!ret) after reviewing all handlers: */
        qobject_unref(ret);
        goto out;
    }

    if (cmd->options & QCO_NO_SUCCESS_RESP) {
        g_assert(!ret);
        return NULL;
    } else if (!ret) {
        /*
         * When the command's schema has no 'returns', cmd->fn()
         * leaves @ret null.  The QMP spec calls for an empty object
         * then; supply it.
         */
        ret = QOBJECT(qdict_new());
    }

    rsp = qdict_new();
    qdict_put_obj(rsp, "return", ret);

out:
    if (err) {
        assert(!rsp);
        rsp = qmp_error_response(err);
    }

    assert(rsp);

    if (id) {
        qdict_put_obj(rsp, "id", qobject_ref(id));
    }

    return rsp;
}
