/*
 * 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 "json-lexer.h"
#include "json-parser.h"
#include "json-streamer.h"
#include "qjson.h"
#include "qint.h"
#include "qlist.h"
#include "qbool.h"
#include "qfloat.h"
#include "qdict.h"

typedef struct JSONParsingState
{
    JSONMessageParser parser;
    va_list *ap;
    QObject *result;
} JSONParsingState;

static void parse_json(JSONMessageParser *parser, QList *tokens)
{
    JSONParsingState *s = container_of(parser, JSONParsingState, parser);
    s->result = json_parser_parse(tokens, s->ap);
}

QObject *qobject_from_jsonv(const char *string, va_list *ap)
{
    JSONParsingState state = {};

    state.ap = ap;

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

    return state.result;
}

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

QObject *qobject_from_jsonf(const char *string, ...)
{
    QObject *obj;
    va_list ap;

    va_start(ap, string);
    obj = qobject_from_jsonv(string, &ap);
    va_end(ap);

    return obj;
}

typedef struct ToJsonIterState
{
    int count;
    QString *str;
} ToJsonIterState;

static void to_json(const QObject *obj, QString *str);

static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
{
    ToJsonIterState *s = opaque;
    QString *qkey;

    if (s->count) {
        qstring_append(s->str, ", ");
    }

    qkey = qstring_from_str(key);
    to_json(QOBJECT(qkey), s->str);
    QDECREF(qkey);

    qstring_append(s->str, ": ");
    to_json(obj, s->str);
    s->count++;
}

static void to_json_list_iter(QObject *obj, void *opaque)
{
    ToJsonIterState *s = opaque;

    if (s->count) {
        qstring_append(s->str, ", ");
    }

    to_json(obj, s->str);
    s->count++;
}

static void to_json(const QObject *obj, QString *str)
{
    switch (qobject_type(obj)) {
    case QTYPE_QINT: {
        QInt *val = qobject_to_qint(obj);
        char buffer[1024];

        snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
        qstring_append(str, buffer);
        break;
    }
    case QTYPE_QSTRING: {
        QString *val = qobject_to_qstring(obj);
        const char *ptr;

        ptr = qstring_get_str(val);
        qstring_append(str, "\"");
        while (*ptr) {
            if ((ptr[0] & 0xE0) == 0xE0 &&
                (ptr[1] & 0x80) && (ptr[2] & 0x80)) {
                uint16_t wchar;
                char escape[7];

                wchar  = (ptr[0] & 0x0F) << 12;
                wchar |= (ptr[1] & 0x3F) << 6;
                wchar |= (ptr[2] & 0x3F);
                ptr += 2;

                snprintf(escape, sizeof(escape), "\\u%04X", wchar);
                qstring_append(str, escape);
            } else if ((ptr[0] & 0xE0) == 0xC0 && (ptr[1] & 0x80)) {
                uint16_t wchar;
                char escape[7];

                wchar  = (ptr[0] & 0x1F) << 6;
                wchar |= (ptr[1] & 0x3F);
                ptr++;

                snprintf(escape, sizeof(escape), "\\u%04X", wchar);
                qstring_append(str, escape);
            } else switch (ptr[0]) {
                case '\"':
                    qstring_append(str, "\\\"");
                    break;
                case '\\':
                    qstring_append(str, "\\\\");
                    break;
                case '\b':
                    qstring_append(str, "\\b");
                    break;
                case '\n':
                    qstring_append(str, "\\n");
                    break;
                case '\r':
                    qstring_append(str, "\\r");
                    break;
                case '\t':
                    qstring_append(str, "\\t");
                    break;
                default: {
                    char buf[2] = { ptr[0], 0 };
                    qstring_append(str, buf);
                    break;
                }
                }
            ptr++;
        }
        qstring_append(str, "\"");
        break;
    }
    case QTYPE_QDICT: {
        ToJsonIterState s;
        QDict *val = qobject_to_qdict(obj);

        s.count = 0;
        s.str = str;
        qstring_append(str, "{");
        qdict_iter(val, to_json_dict_iter, &s);
        qstring_append(str, "}");
        break;
    }
    case QTYPE_QLIST: {
        ToJsonIterState s;
        QList *val = qobject_to_qlist(obj);

        s.count = 0;
        s.str = str;
        qstring_append(str, "[");
        qlist_iter(val, (void *)to_json_list_iter, &s);
        qstring_append(str, "]");
        break;
    }
    case QTYPE_QFLOAT: {
        QFloat *val = qobject_to_qfloat(obj);
        char buffer[1024];
        int len;

        len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
        while (len > 0 && buffer[len - 1] == '0') {
            len--;
        }

        if (len && buffer[len - 1] == '.') {
            buffer[len - 1] = 0;
        } else {
            buffer[len] = 0;
        }
        
        qstring_append(str, buffer);
        break;
    }
    case QTYPE_QBOOL: {
        QBool *val = qobject_to_qbool(obj);

        if (qbool_get_int(val)) {
            qstring_append(str, "true");
        } else {
            qstring_append(str, "false");
        }
        break;
    }
    case QTYPE_QERROR:
        /* XXX: should QError be emitted? */
    case QTYPE_NONE:
        break;
    }
}

QString *qobject_to_json(const QObject *obj)
{
    QString *str = qstring_new();

    to_json(obj, str);

    return str;
}
