/*
 * JSON Writer
 *
 * Copyright IBM, Corp. 2009
 * Copyright (c) 2010-2020 Red Hat Inc.
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *  Markus Armbruster <armbru@redhat.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/qmp/json-writer.h"
#include "qemu/unicode.h"

struct JSONWriter {
    bool pretty;
    bool need_comma;
    GString *contents;
    GByteArray *container_is_array;
};

JSONWriter *json_writer_new(bool pretty)
{
    JSONWriter *writer = g_new(JSONWriter, 1);

    writer->pretty = pretty;
    writer->need_comma = false;
    writer->contents = g_string_new(NULL);
    writer->container_is_array = g_byte_array_new();
    return writer;
}

const char *json_writer_get(JSONWriter *writer)
{
    g_assert(!writer->container_is_array->len);
    return writer->contents->str;
}

GString *json_writer_get_and_free(JSONWriter *writer)
{
    GString *contents = writer->contents;

    writer->contents = NULL;
    g_byte_array_free(writer->container_is_array, true);
    g_free(writer);
    return contents;
}

void json_writer_free(JSONWriter *writer)
{
    if (writer) {
        g_string_free(json_writer_get_and_free(writer), true);
    }
}

static void enter_container(JSONWriter *writer, bool is_array)
{
    unsigned depth = writer->container_is_array->len;

    g_byte_array_set_size(writer->container_is_array, depth + 1);
    writer->container_is_array->data[depth] = is_array;
    writer->need_comma = false;
}

static void leave_container(JSONWriter *writer, bool is_array)
{
    unsigned depth = writer->container_is_array->len;

    assert(depth);
    assert(writer->container_is_array->data[depth - 1] == is_array);
    g_byte_array_set_size(writer->container_is_array, depth - 1);
    writer->need_comma = true;
}

static bool in_object(JSONWriter *writer)
{
    unsigned depth = writer->container_is_array->len;

    return depth && !writer->container_is_array->data[depth - 1];
}

static void pretty_newline(JSONWriter *writer)
{
    if (writer->pretty) {
        g_string_append_printf(writer->contents, "\n%*s",
                               writer->container_is_array->len * 4, "");
    }
}

static void pretty_newline_or_space(JSONWriter *writer)
{
    if (writer->pretty) {
        g_string_append_printf(writer->contents, "\n%*s",
                               writer->container_is_array->len * 4, "");
    } else {
        g_string_append_c(writer->contents, ' ');
    }
}

static void quoted_str(JSONWriter *writer, const char *str)
{
    const char *ptr;
    char *end;
    int cp;

    g_string_append_c(writer->contents, '"');

    for (ptr = str; *ptr; ptr = end) {
        cp = mod_utf8_codepoint(ptr, 6, &end);
        switch (cp) {
        case '\"':
            g_string_append(writer->contents, "\\\"");
            break;
        case '\\':
            g_string_append(writer->contents, "\\\\");
            break;
        case '\b':
            g_string_append(writer->contents, "\\b");
            break;
        case '\f':
            g_string_append(writer->contents, "\\f");
            break;
        case '\n':
            g_string_append(writer->contents, "\\n");
            break;
        case '\r':
            g_string_append(writer->contents, "\\r");
            break;
        case '\t':
            g_string_append(writer->contents, "\\t");
            break;
        default:
            if (cp < 0) {
                cp = 0xFFFD; /* replacement character */
            }
            if (cp > 0xFFFF) {
                /* beyond BMP; need a surrogate pair */
                g_string_append_printf(writer->contents, "\\u%04X\\u%04X",
                                       0xD800 + ((cp - 0x10000) >> 10),
                                       0xDC00 + ((cp - 0x10000) & 0x3FF));
            } else if (cp < 0x20 || cp >= 0x7F) {
                g_string_append_printf(writer->contents, "\\u%04X", cp);
            } else {
                g_string_append_c(writer->contents, cp);
            }
        }
    };

    g_string_append_c(writer->contents, '"');
}

static void maybe_comma_name(JSONWriter *writer, const char *name)
{
    if (writer->need_comma) {
        g_string_append_c(writer->contents, ',');
        pretty_newline_or_space(writer);
    } else {
        if (writer->contents->len) {
            pretty_newline(writer);
        }
        writer->need_comma = true;
    }

    if (in_object(writer)) {
        quoted_str(writer, name);
        g_string_append(writer->contents, ": ");
    }
}

void json_writer_start_object(JSONWriter *writer, const char *name)
{
    maybe_comma_name(writer, name);
    g_string_append_c(writer->contents, '{');
    enter_container(writer, false);
}

void json_writer_end_object(JSONWriter *writer)
{
    leave_container(writer, false);
    pretty_newline(writer);
    g_string_append_c(writer->contents, '}');
}

void json_writer_start_array(JSONWriter *writer, const char *name)
{
    maybe_comma_name(writer, name);
    g_string_append_c(writer->contents, '[');
    enter_container(writer, true);
}

void json_writer_end_array(JSONWriter *writer)
{
    leave_container(writer, true);
    pretty_newline(writer);
    g_string_append_c(writer->contents, ']');
}

void json_writer_bool(JSONWriter *writer, const char *name, bool val)
{
    maybe_comma_name(writer, name);
    g_string_append(writer->contents, val ? "true" : "false");
}

void json_writer_null(JSONWriter *writer, const char *name)
{
    maybe_comma_name(writer, name);
    g_string_append(writer->contents, "null");
}

void json_writer_int64(JSONWriter *writer, const char *name, int64_t val)
{
    maybe_comma_name(writer, name);
    g_string_append_printf(writer->contents, "%" PRId64, val);
}

void json_writer_uint64(JSONWriter *writer, const char *name, uint64_t val)
{
    maybe_comma_name(writer, name);
    g_string_append_printf(writer->contents, "%" PRIu64, val);
}

void json_writer_double(JSONWriter *writer, const char *name, double val)
{
    maybe_comma_name(writer, name);

    /*
     * FIXME: g_string_append_printf() is locale dependent; but JSON
     * requires numbers to be formatted as if in the C locale.
     * Dependence on C locale is a pervasive issue in QEMU.
     */
    /*
     * FIXME: This risks printing Inf or NaN, which are not valid
     * JSON values.
     */
    g_string_append_printf(writer->contents, "%.17g", val);
}

void json_writer_str(JSONWriter *writer, const char *name, const char *str)
{
    maybe_comma_name(writer, name);
    quoted_str(writer, str);
}
