/*
 * QObject JSON integration
 *
 * Copyright IBM, Corp. 2009
 *
 * 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 "qapi/error.h"
#include "qobject/json-parser.h"
#include "qobject/json-writer.h"
#include "qobject/qjson.h"
#include "qobject/qbool.h"
#include "qobject/qdict.h"
#include "qobject/qlist.h"
#include "qobject/qnum.h"
#include "qobject/qstring.h"

typedef struct JSONParsingState {
    JSONMessageParser parser;
    QObject *result;
    Error *err;
} JSONParsingState;

static void consume_json(void *opaque, QObject *json, Error *err)
{
    JSONParsingState *s = opaque;

    assert(!json != !err);
    assert(!s->result || !s->err);

    if (s->result) {
        qobject_unref(s->result);
        s->result = NULL;
        error_setg(&s->err, "Expecting at most one JSON value");
    }
    if (s->err) {
        qobject_unref(json);
        error_free(err);
        return;
    }
    s->result = json;
    s->err = err;
}

/*
 * Parse @string as JSON value.
 * If @ap is non-null, interpolate %-escapes.
 * Takes ownership of %p arguments.
 * On success, return the JSON value.
 * On failure, store an error through @errp and return NULL.
 * Ownership of %p arguments becomes indeterminate then.  To avoid
 * leaks, callers passing %p must terminate on error, e.g. by passing
 * &error_abort.
 */
static QObject *qobject_from_jsonv(const char *string, va_list *ap,
                                   Error **errp)
{
    JSONParsingState state = {};

    json_message_parser_init(&state.parser, consume_json, &state, ap);
    json_message_parser_feed(&state.parser, string, strlen(string));
    json_message_parser_flush(&state.parser);
    json_message_parser_destroy(&state.parser);

    if (!state.result && !state.err) {
        error_setg(&state.err, "Expecting a JSON value");
    }

    error_propagate(errp, state.err);
    return state.result;
}

QObject *qobject_from_json(const char *string, Error **errp)
{
    return qobject_from_jsonv(string, NULL, errp);
}

/*
 * Parse @string as JSON value with %-escapes interpolated.
 * Abort on error.  Do not use with untrusted @string.
 * Return the resulting QObject.  It is never null.
 */
QObject *qobject_from_vjsonf_nofail(const char *string, va_list ap)
{
    va_list ap_copy;
    QObject *obj;

    /* va_copy() is needed when va_list is an array type */
    va_copy(ap_copy, ap);
    obj = qobject_from_jsonv(string, &ap_copy, &error_abort);
    va_end(ap_copy);

    assert(obj);
    return obj;
}

/*
 * Parse @string as JSON value with %-escapes interpolated.
 * Abort on error.  Do not use with untrusted @string.
 * Return the resulting QObject.  It is never null.
 */
QObject *qobject_from_jsonf_nofail(const char *string, ...)
{
    QObject *obj;
    va_list ap;

    va_start(ap, string);
    obj = qobject_from_vjsonf_nofail(string, ap);
    va_end(ap);

    return obj;
}

/*
 * Parse @string as JSON object with %-escapes interpolated.
 * Abort on error.  Do not use with untrusted @string.
 * Return the resulting QDict.  It is never null.
 */
QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
{
    QDict *qdict;

    qdict = qobject_to(QDict, qobject_from_vjsonf_nofail(string, ap));
    assert(qdict);
    return qdict;
}

/*
 * Parse @string as JSON object with %-escapes interpolated.
 * Abort on error.  Do not use with untrusted @string.
 * Return the resulting QDict.  It is never null.
 */
QDict *qdict_from_jsonf_nofail(const char *string, ...)
{
    QDict *qdict;
    va_list ap;

    va_start(ap, string);
    qdict = qdict_from_vjsonf_nofail(string, ap);
    va_end(ap);
    return qdict;
}

static void to_json(JSONWriter *writer, const char *name,
                    const QObject *obj)
{
    switch (qobject_type(obj)) {
    case QTYPE_QNULL:
        json_writer_null(writer, name);
        break;
    case QTYPE_QNUM: {
        QNum *val = qobject_to(QNum, obj);

        switch (val->kind) {
        case QNUM_I64:
            json_writer_int64(writer, name, val->u.i64);
            break;
        case QNUM_U64:
            json_writer_uint64(writer, name, val->u.u64);
            break;
        case QNUM_DOUBLE:
            json_writer_double(writer, name, val->u.dbl);
            break;
        default:
            abort();
        }
        break;
    }
    case QTYPE_QSTRING: {
        QString *val = qobject_to(QString, obj);

        json_writer_str(writer, name, qstring_get_str(val));
        break;
    }
    case QTYPE_QDICT: {
        QDict *val = qobject_to(QDict, obj);
        const QDictEntry *entry;

        json_writer_start_object(writer, name);

        for (entry = qdict_first(val);
             entry;
             entry = qdict_next(val, entry)) {
            to_json(writer, qdict_entry_key(entry), qdict_entry_value(entry));
        }

        json_writer_end_object(writer);
        break;
    }
    case QTYPE_QLIST: {
        QList *val = qobject_to(QList, obj);
        QListEntry *entry;

        json_writer_start_array(writer, name);

        QLIST_FOREACH_ENTRY(val, entry) {
            to_json(writer, NULL, qlist_entry_obj(entry));
        }

        json_writer_end_array(writer);
        break;
    }
    case QTYPE_QBOOL: {
        QBool *val = qobject_to(QBool, obj);

        json_writer_bool(writer, name, qbool_get_bool(val));
        break;
    }
    default:
        abort();
    }
}

GString *qobject_to_json_pretty(const QObject *obj, bool pretty)
{
    JSONWriter *writer = json_writer_new(pretty);

    to_json(writer, NULL, obj);
    return json_writer_get_and_free(writer);
}

GString *qobject_to_json(const QObject *obj)
{
    return qobject_to_json_pretty(obj, false);
}
