/*
 * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
 * Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
 *
 * Jansson is free software; you can redistribute it and/or modify
 * it under the terms of the MIT license. See LICENSE for details.
 */

#include <string.h>
#include "jansson.h"
#include "jansson_private.h"
#include "utf.h"

typedef struct {
    int line;
    int column;
    size_t pos;
    char token;
} token_t;

typedef struct {
    const char *start;
    const char *fmt;
    token_t prev_token;
    token_t token;
    token_t next_token;
    json_error_t *error;
    size_t flags;
    int line;
    int column;
    size_t pos;
} scanner_t;

#define token(scanner) ((scanner)->token.token)

static const char * const type_names[] = {
    "object",
    "array",
    "string",
    "integer",
    "real",
    "true",
    "false",
    "null"
};

#define type_name(x) type_names[json_typeof(x)]

static const char unpack_value_starters[] = "{[siIbfFOon";


static void scanner_init(scanner_t *s, json_error_t *error,
                         size_t flags, const char *fmt)
{
    s->error = error;
    s->flags = flags;
    s->fmt = s->start = fmt;
    memset(&s->prev_token, 0, sizeof(token_t));
    memset(&s->token, 0, sizeof(token_t));
    memset(&s->next_token, 0, sizeof(token_t));
    s->line = 1;
    s->column = 0;
    s->pos = 0;
}

static void next_token(scanner_t *s)
{
    const char *t;
    s->prev_token = s->token;

    if(s->next_token.line) {
        s->token = s->next_token;
        s->next_token.line = 0;
        return;
    }

    t = s->fmt;
    s->column++;
    s->pos++;

    /* skip space and ignored chars */
    while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
        if(*t == '\n') {
            s->line++;
            s->column = 1;
        }
        else
            s->column++;

        s->pos++;
        t++;
    }

    s->token.token = *t;
    s->token.line = s->line;
    s->token.column = s->column;
    s->token.pos = s->pos;

    t++;
    s->fmt = t;
}

static void prev_token(scanner_t *s)
{
    s->next_token = s->token;
    s->token = s->prev_token;
}

static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
                     fmt, ap);

    jsonp_error_set_source(s->error, source);

    va_end(ap);
}

static json_t *pack(scanner_t *s, va_list *ap);


/* ours will be set to 1 if jsonp_free() must be called for the result
   afterwards */
static char *read_string(scanner_t *s, va_list *ap,
                         const char *purpose, size_t *out_len, int *ours)
{
    char t;
    strbuffer_t strbuff;
    const char *str;
    size_t length;

    next_token(s);
    t = token(s);
    prev_token(s);

    if(t != '#' && t != '%' && t != '+') {
        /* Optimize the simple case */
        str = va_arg(*ap, const char *);

        if(!str) {
            set_error(s, "<args>", "NULL string argument");
            return NULL;
        }

        length = strlen(str);

        if(!utf8_check_string(str, length)) {
            set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
            return NULL;
        }

        *out_len = length;
        *ours = 0;
        return (char *)str;
    }

    strbuffer_init(&strbuff);

    while(1) {
        str = va_arg(*ap, const char *);
        if(!str) {
            set_error(s, "<args>", "NULL string argument");
            strbuffer_close(&strbuff);
            return NULL;
        }

        next_token(s);

        if(token(s) == '#') {
            length = va_arg(*ap, int);
        }
        else if(token(s) == '%') {
            length = va_arg(*ap, size_t);
        }
        else {
            prev_token(s);
            length = strlen(str);
        }

        if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
            set_error(s, "<internal>", "Out of memory");
            strbuffer_close(&strbuff);
            return NULL;
        }

        next_token(s);
        if(token(s) != '+') {
            prev_token(s);
            break;
        }
    }

    if(!utf8_check_string(strbuff.value, strbuff.length)) {
        set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
        strbuffer_close(&strbuff);
        return NULL;
    }

    *out_len = strbuff.length;
    *ours = 1;
    return strbuffer_steal_value(&strbuff);
}

static json_t *pack_object(scanner_t *s, va_list *ap)
{
    json_t *object = json_object();
    next_token(s);

    while(token(s) != '}') {
        char *key;
        size_t len;
        int ours;
        json_t *value;

        if(!token(s)) {
            set_error(s, "<format>", "Unexpected end of format string");
            goto error;
        }

        if(token(s) != 's') {
            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
            goto error;
        }

        key = read_string(s, ap, "object key", &len, &ours);
        if(!key)
            goto error;

        next_token(s);

        value = pack(s, ap);
        if(!value) {
            if(ours)
                jsonp_free(key);

            goto error;
        }

        if(json_object_set_new_nocheck(object, key, value)) {
            if(ours)
                jsonp_free(key);

            set_error(s, "<internal>", "Unable to add key \"%s\"", key);
            goto error;
        }

        if(ours)
            jsonp_free(key);

        next_token(s);
    }

    return object;

error:
    json_decref(object);
    return NULL;
}

static json_t *pack_array(scanner_t *s, va_list *ap)
{
    json_t *array = json_array();
    next_token(s);

    while(token(s) != ']') {
        json_t *value;

        if(!token(s)) {
            set_error(s, "<format>", "Unexpected end of format string");
            goto error;
        }

        value = pack(s, ap);
        if(!value)
            goto error;

        if(json_array_append_new(array, value)) {
            set_error(s, "<internal>", "Unable to append to array");
            goto error;
        }

        next_token(s);
    }
    return array;

error:
    json_decref(array);
    return NULL;
}

static json_t *pack(scanner_t *s, va_list *ap)
{
    switch(token(s)) {
        case '{':
            return pack_object(s, ap);

        case '[':
            return pack_array(s, ap);

        case 's': /* string */
        {
            char *str;
            size_t len;
            int ours;

            str = read_string(s, ap, "string", &len, &ours);
            if(!str)
                return NULL;

            if (ours)
                return jsonp_stringn_nocheck_own(str, len);
            else
                return json_stringn_nocheck(str, len);
        }

        case 'n': /* null */
            return json_null();

        case 'b': /* boolean */
            return va_arg(*ap, int) ? json_true() : json_false();

        case 'i': /* integer from int */
            return json_integer(va_arg(*ap, int));

        case 'I': /* integer from json_int_t */
            return json_integer(va_arg(*ap, json_int_t));

        case 'f': /* real */
            return json_real(va_arg(*ap, double));

        case 'O': /* a json_t object; increments refcount */
            return json_incref(va_arg(*ap, json_t *));

        case 'o': /* a json_t object; doesn't increment refcount */
            return va_arg(*ap, json_t *);

        default:
            set_error(s, "<format>", "Unexpected format character '%c'",
                      token(s));
            return NULL;
    }
}

static int unpack(scanner_t *s, json_t *root, va_list *ap);

static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
{
    int ret = -1;
    int strict = 0;
    int gotopt = 0;

    /* Use a set (emulated by a hashtable) to check that all object
       keys are accessed. Checking that the correct number of keys
       were accessed is not enough, as the same key can be unpacked
       multiple times.
    */
    hashtable_t key_set;

    if(hashtable_init(&key_set)) {
        set_error(s, "<internal>", "Out of memory");
        return -1;
    }

    if(root && !json_is_object(root)) {
        set_error(s, "<validation>", "Expected object, got %s",
                  type_name(root));
        goto out;
    }
    next_token(s);

    while(token(s) != '}') {
        const char *key;
        json_t *value;
        int opt = 0;

        if(strict != 0) {
            set_error(s, "<format>", "Expected '}' after '%c', got '%c'",
                      (strict == 1 ? '!' : '*'), token(s));
            goto out;
        }

        if(!token(s)) {
            set_error(s, "<format>", "Unexpected end of format string");
            goto out;
        }

        if(token(s) == '!' || token(s) == '*') {
            strict = (token(s) == '!' ? 1 : -1);
            next_token(s);
            continue;
        }

        if(token(s) != 's') {
            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
            goto out;
        }

        key = va_arg(*ap, const char *);
        if(!key) {
            set_error(s, "<args>", "NULL object key");
            goto out;
        }

        next_token(s);

        if(token(s) == '?') {
            opt = gotopt = 1;
            next_token(s);
        }

        if(!root) {
            /* skipping */
            value = NULL;
        }
        else {
            value = json_object_get(root, key);
            if(!value && !opt) {
                set_error(s, "<validation>", "Object item not found: %s", key);
                goto out;
            }
        }

        if(unpack(s, value, ap))
            goto out;

        hashtable_set(&key_set, key, 0, json_null());
        next_token(s);
    }

    if(strict == 0 && (s->flags & JSON_STRICT))
        strict = 1;

    if(root && strict == 1) {
        /* We need to check that all non optional items have been parsed */
        const char *key;
        json_t *value;
        long unpacked = 0;
        if (gotopt) {
            /* We have optional keys, we need to iter on each key */
            json_object_foreach(root, key, value) {
                if(!hashtable_get(&key_set, key)) {
                    unpacked++;
                }
            }
        } else {
            /* No optional keys, we can just compare the number of items */
            unpacked = (long)json_object_size(root) - (long)key_set.size;
        }
        if (unpacked) {
            set_error(s, "<validation>", "%li object item(s) left unpacked", unpacked);
            goto out;
        }
    }

    ret = 0;

out:
    hashtable_close(&key_set);
    return ret;
}

static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
{
    size_t i = 0;
    int strict = 0;

    if(root && !json_is_array(root)) {
        set_error(s, "<validation>", "Expected array, got %s", type_name(root));
        return -1;
    }
    next_token(s);

    while(token(s) != ']') {
        json_t *value;

        if(strict != 0) {
            set_error(s, "<format>", "Expected ']' after '%c', got '%c'",
                      (strict == 1 ? '!' : '*'),
                      token(s));
            return -1;
        }

        if(!token(s)) {
            set_error(s, "<format>", "Unexpected end of format string");
            return -1;
        }

        if(token(s) == '!' || token(s) == '*') {
            strict = (token(s) == '!' ? 1 : -1);
            next_token(s);
            continue;
        }

        if(!strchr(unpack_value_starters, token(s))) {
            set_error(s, "<format>", "Unexpected format character '%c'",
                      token(s));
            return -1;
        }

        if(!root) {
            /* skipping */
            value = NULL;
        }
        else {
            value = json_array_get(root, i);
            if(!value) {
                set_error(s, "<validation>", "Array index %lu out of range",
                          (unsigned long)i);
                return -1;
            }
        }

        if(unpack(s, value, ap))
            return -1;

        next_token(s);
        i++;
    }

    if(strict == 0 && (s->flags & JSON_STRICT))
        strict = 1;

    if(root && strict == 1 && i != json_array_size(root)) {
        long diff = (long)json_array_size(root) - (long)i;
        set_error(s, "<validation>", "%li array item(s) left unpacked", diff);
        return -1;
    }

    return 0;
}

static int unpack(scanner_t *s, json_t *root, va_list *ap)
{
    switch(token(s))
    {
        case '{':
            return unpack_object(s, root, ap);

        case '[':
            return unpack_array(s, root, ap);

        case 's':
            if(root && !json_is_string(root)) {
                set_error(s, "<validation>", "Expected string, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                const char **str_target;
                size_t *len_target = NULL;

                str_target = va_arg(*ap, const char **);
                if(!str_target) {
                    set_error(s, "<args>", "NULL string argument");
                    return -1;
                }

                next_token(s);

                if(token(s) == '%') {
                    len_target = va_arg(*ap, size_t *);
                    if(!len_target) {
                        set_error(s, "<args>", "NULL string length argument");
                        return -1;
                    }
                }
                else
                    prev_token(s);

                if(root) {
                    *str_target = json_string_value(root);
                    if(len_target)
                        *len_target = json_string_length(root);
                }
            }
            return 0;

        case 'i':
            if(root && !json_is_integer(root)) {
                set_error(s, "<validation>", "Expected integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                int *target = va_arg(*ap, int*);
                if(root)
                    *target = (int)json_integer_value(root);
            }

            return 0;

        case 'I':
            if(root && !json_is_integer(root)) {
                set_error(s, "<validation>", "Expected integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                json_int_t *target = va_arg(*ap, json_int_t*);
                if(root)
                    *target = json_integer_value(root);
            }

            return 0;

        case 'b':
            if(root && !json_is_boolean(root)) {
                set_error(s, "<validation>", "Expected true or false, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                int *target = va_arg(*ap, int*);
                if(root)
                    *target = json_is_true(root);
            }

            return 0;

        case 'f':
            if(root && !json_is_real(root)) {
                set_error(s, "<validation>", "Expected real, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                double *target = va_arg(*ap, double*);
                if(root)
                    *target = json_real_value(root);
            }

            return 0;

        case 'F':
            if(root && !json_is_number(root)) {
                set_error(s, "<validation>", "Expected real or integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                double *target = va_arg(*ap, double*);
                if(root)
                    *target = json_number_value(root);
            }

            return 0;

        case 'O':
            if(root && !(s->flags & JSON_VALIDATE_ONLY))
                json_incref(root);
            /* Fall through */

        case 'o':
            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                json_t **target = va_arg(*ap, json_t**);
                if(root)
                    *target = root;
            }

            return 0;

        case 'n':
            /* Never assign, just validate */
            if(root && !json_is_null(root)) {
                set_error(s, "<validation>", "Expected null, got %s",
                          type_name(root));
                return -1;
            }
            return 0;

        default:
            set_error(s, "<format>", "Unexpected format character '%c'",
                      token(s));
            return -1;
    }
}

json_t *json_vpack_ex(json_error_t *error, size_t flags,
                      const char *fmt, va_list ap)
{
    scanner_t s;
    va_list ap_copy;
    json_t *value;

    if(!fmt || !*fmt) {
        jsonp_error_init(error, "<format>");
        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
        return NULL;
    }
    jsonp_error_init(error, NULL);

    scanner_init(&s, error, flags, fmt);
    next_token(&s);

    va_copy(ap_copy, ap);
    value = pack(&s, &ap_copy);
    va_end(ap_copy);

    if(!value)
        return NULL;

    next_token(&s);
    if(token(&s)) {
        json_decref(value);
        set_error(&s, "<format>", "Garbage after format string");
        return NULL;
    }

    return value;
}

json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
{
    json_t *value;
    va_list ap;

    va_start(ap, fmt);
    value = json_vpack_ex(error, flags, fmt, ap);
    va_end(ap);

    return value;
}

json_t *json_pack(const char *fmt, ...)
{
    json_t *value;
    va_list ap;

    va_start(ap, fmt);
    value = json_vpack_ex(NULL, 0, fmt, ap);
    va_end(ap);

    return value;
}

int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
                    const char *fmt, va_list ap)
{
    scanner_t s;
    va_list ap_copy;

    if(!root) {
        jsonp_error_init(error, "<root>");
        jsonp_error_set(error, -1, -1, 0, "NULL root value");
        return -1;
    }

    if(!fmt || !*fmt) {
        jsonp_error_init(error, "<format>");
        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
        return -1;
    }
    jsonp_error_init(error, NULL);

    scanner_init(&s, error, flags, fmt);
    next_token(&s);

    va_copy(ap_copy, ap);
    if(unpack(&s, root, &ap_copy)) {
        va_end(ap_copy);
        return -1;
    }
    va_end(ap_copy);

    next_token(&s);
    if(token(&s)) {
        set_error(&s, "<format>", "Garbage after format string");
        return -1;
    }

    return 0;
}

int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
{
    int ret;
    va_list ap;

    va_start(ap, fmt);
    ret = json_vunpack_ex(root, error, flags, fmt, ap);
    va_end(ap);

    return ret;
}

int json_unpack(json_t *root, const char *fmt, ...)
{
    int ret;
    va_list ap;

    va_start(ap, fmt);
    ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
    va_end(ap);

    return ret;
}
