/**
 * @file json.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief Generic JSON format parser for libyang
 *
 * Copyright (c) 2020 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#include "common.h"
#include "json.h"
#include "in_internal.h"

#define JSON_PUSH_STATUS_RET(CTX, STATUS) \
    LY_CHECK_RET(ly_set_add(&CTX->status, (void*)STATUS, 1, NULL))

#define JSON_POP_STATUS_RET(CTX) \
    assert(CTX->status.count); CTX->status.count--;

const char *
lyjson_token2str(enum LYJSON_PARSER_STATUS status)
{
    switch (status) {
    case LYJSON_ERROR:
        return "error";
    case LYJSON_ROOT:
        return "document root";
    case LYJSON_FALSE:
        return "false";
    case LYJSON_TRUE:
        return "true";
    case LYJSON_NULL:
        return "null";
    case LYJSON_OBJECT:
        return "object";
    case LYJSON_OBJECT_CLOSED:
        return "object closed";
    case LYJSON_OBJECT_EMPTY:
        return "empty object";
    case LYJSON_ARRAY:
        return "array";
    case LYJSON_ARRAY_CLOSED:
        return "array closed";
    case LYJSON_ARRAY_EMPTY:
        return "empty array";
    case LYJSON_NUMBER:
        return "number";
    case LYJSON_STRING:
        return "string";
    case LYJSON_END:
        return "end of input";
    }

    return "";
}

static LY_ERR
skip_ws(struct lyjson_ctx *jsonctx)
{
    /* skip leading whitespaces */
    while (*jsonctx->in->current != '\0' && is_jsonws(*jsonctx->in->current)) {
        if (*jsonctx->in->current == 0x0a) { /* new line */
            jsonctx->line++;
        }
        ly_in_skip(jsonctx->in, 1);
    }
    if (*jsonctx->in->current == '\0') {
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_END);
    }

    return LY_SUCCESS;
}

/*
 * @brief Set value corresponding to the current context's status
 */
static void
lyjson_ctx_set_value(struct lyjson_ctx *jsonctx, const char *value, size_t value_len, ly_bool dynamic)
{
    assert(jsonctx);

    if (dynamic) {
        free((char *)jsonctx->value);
    }
    jsonctx->value = value;
    jsonctx->value_len = value_len;
    jsonctx->dynamic = dynamic;
}

static LY_ERR
lyjson_check_next(struct lyjson_ctx *jsonctx)
{
    if (jsonctx->status.count == 1) {
        /* top level value (JSON-text), ws expected */
        if ((*jsonctx->in->current == '\0') || is_jsonws(*jsonctx->in->current)) {
            return LY_SUCCESS;
        }
    } else if (lyjson_ctx_status(jsonctx, 1) == LYJSON_OBJECT) {
        LY_CHECK_RET(skip_ws(jsonctx));
        if ((*jsonctx->in->current == ',') || (*jsonctx->in->current == '}')) {
            return LY_SUCCESS;
        }
    } else if (lyjson_ctx_status(jsonctx, 1) == LYJSON_ARRAY) {
        LY_CHECK_RET(skip_ws(jsonctx));
        if ((*jsonctx->in->current == ',') || (*jsonctx->in->current == ']')) {
            return LY_SUCCESS;
        }
    } else {
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
                "Unexpected character \"%c\" after JSON %s.", *jsonctx->in->current, lyjson_token2str(lyjson_ctx_status(jsonctx, 0)));
    }

    return LY_EVALID;
}

/**
 * Input is expected to start after the opening quotation-mark.
 * When succeeds, input is moved after the closing quotation-mark.
 */
static LY_ERR
lyjson_string_(struct lyjson_ctx *jsonctx)
{
#define BUFSIZE 24
#define BUFSIZE_STEP 128

    const char *in = jsonctx->in->current, *start;
    char *buf = NULL;
    size_t offset;   /* read offset in input buffer */
    size_t len;      /* length of the output string (write offset in output buffer) */
    size_t size = 0; /* size of the output buffer */
    size_t u;
    uint64_t start_line;

    assert(jsonctx);

    /* init */
    start = in;
    start_line = jsonctx->line;
    offset = len = 0;

    /* parse */
    while (in[offset]) {
        if (in[offset] == '\\') {
            /* escape sequence */
            size_t slash = offset;
            uint32_t value;
            uint8_t i = 1;

            if (!buf) {
                /* prepare output buffer */
                buf = malloc(BUFSIZE);
                LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                size = BUFSIZE;
            }

            /* allocate enough for the offset and next character,
             * we will need 4 bytes at most since we support only the predefined
             * (one-char) entities and character references */
            if (len + offset + 4 >= size) {
                buf = ly_realloc(buf, size + BUFSIZE_STEP);
                LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                size += BUFSIZE_STEP;
            }

            if (offset) {
                /* store what we have so far */
                memcpy(&buf[len], in, offset);
                len += offset;
                in += offset;
                offset = 0;
            }

            switch (in[++offset]) {
            case '"':
                /* quotation mark */
                value = 0x22;
                break;
            case '\\':
                /* reverse solidus */
                value = 0x5c;
                break;
            case '/':
                /* solidus */
                value = 0x2f;
                break;
            case 'b':
                /* backspace */
                value = 0x08;
                break;
            case 'f':
                /* form feed */
                value = 0x0c;
                break;
            case 'n':
                /* line feed */
                value = 0x0a;
                break;
            case 'r':
                /* carriage return */
                value = 0x0d;
                break;
            case 't':
                /* tab */
                value = 0x09;
                break;
            case 'u':
                /* Basic Multilingual Plane character \uXXXX */
                offset++;
                for (value = i = 0; i < 4; i++) {
                    if (isdigit(in[offset + i])) {
                        u = (in[offset + i] - '0');
                    } else if (in[offset + i] > 'F') {
                        u = 10 + (in[offset + i] - 'a');
                    } else {
                        u = 10 + (in[offset + i] - 'A');
                    }
                    value = (16 * value) + u;
                }
                break;
            default:
                /* invalid escape sequence */
                LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
                        "Invalid character escape sequence \\%c.", in[offset]);
                goto error;

            }

            offset += i;   /* add read escaped characters */
            LY_CHECK_ERR_GOTO(ly_pututf8(&buf[len], value, &u),
                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
                    "Invalid character reference \"%.*s\" (0x%08x).", offset - slash, &in[slash], value),
                    error);
            len += u;      /* update number of bytes in buffer */
            in += offset;  /* move the input by the processed bytes stored in the buffer ... */
            offset = 0;    /* ... and reset the offset index for future moving data into buffer */

        } else if (in[offset] == '"') {
            /* end of string */
            if (buf) {
                /* realloc exact size string */
                buf = ly_realloc(buf, len + offset + 1);
                LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                size = len + offset + 1;
                memcpy(&buf[len], in, offset);

                /* set terminating NULL byte */
                buf[len + offset] = '\0';
            }
            len += offset;
            ++offset;
            in += offset;
            goto success;
        } else {
            /* get it as UTF-8 character for check */
            const char *c = &in[offset];
            uint32_t code = 0;
            size_t code_len = 0;

            LY_CHECK_ERR_GOTO(ly_getutf8(&c, &code, &code_len),
                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INCHAR, in[offset]), error);

            LY_CHECK_ERR_GOTO(!is_jsonstrchar(code),
                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
                    "Invalid character in JSON string \"%.*s\" (0x%08x).", &in[offset] - start + code_len, start, code),
                    error);

            /* character is ok, continue */
            offset += code_len;
        }
    }

    /* EOF reached before endchar */
    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &start_line, LYVE_SYNTAX, "Missing quotation-mark at the end of a JSON string.");

error:
    free(buf);
    return LY_EVALID;

success:
    ly_in_skip(jsonctx->in, in - jsonctx->in->current);
    if (buf) {
        lyjson_ctx_set_value(jsonctx, buf, len, 1);
    } else {
        lyjson_ctx_set_value(jsonctx, start, len, 0);
    }

    return LY_SUCCESS;

#undef BUFSIZE
#undef BUFSIZE_STEP
}

/*
 *
 * Wrapper around lyjson_string_() adding LYJSON_STRING status into context to allow using lyjson_string_() for parsing object's name.
 */
static LY_ERR
lyjson_string(struct lyjson_ctx *jsonctx)
{
    LY_CHECK_RET(lyjson_string_(jsonctx));

    JSON_PUSH_STATUS_RET(jsonctx, LYJSON_STRING);
    LY_CHECK_RET(lyjson_check_next(jsonctx));

    return LY_SUCCESS;
}

static LY_ERR
lyjson_number(struct lyjson_ctx *jsonctx)
{
    size_t offset = 0, exponent = 0;
    const char *in = jsonctx->in->current;
    uint8_t minus = 0;

    if (in[offset] == '-') {
        ++offset;
        minus = 1;
    }

    if (in[offset] == '0') {
        ++offset;
    } else if (isdigit(in[offset])) {
        ++offset;
        while (isdigit(in[offset])) {
            ++offset;
        }
    } else {
invalid_character:
        if (in[offset]) {
            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
        } else {
            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
        }
        return LY_EVALID;
    }

    if (in[offset] == '.') {
        ++offset;
        if (!isdigit(in[offset])) {
            goto invalid_character;
        }
        while (isdigit(in[offset])) {
            ++offset;
        }
    }

    if ((in[offset] == 'e') || (in[offset] == 'E')) {
        exponent = offset++;
        if ((in[offset] == '+') || (in[offset] == '-')) {
            ++offset;
        }
        if (!isdigit(in[offset])) {
            goto invalid_character;
        }
        while (isdigit(in[offset])) {
            ++offset;
        }
    }

    if (exponent) {
        /* convert JSON number with exponent into the representation used by YANG */
        long int  e_val;
        char *ptr, *dec_point, *num;
        const char *e_ptr = &in[exponent + 1];
        size_t num_len, i;
        int64_t dp_position; /* final position of the deciaml point */

        errno = 0;
        e_val = strtol(e_ptr, &ptr, 10);
        if (errno) {
            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SEMANTICS,
                    "Exponent out-of-bounds in a JSON Number value (%.*s).", offset - minus - (e_ptr - in), e_ptr);
            return LY_EVALID;
        }

        dec_point = ly_strnchr(in, '.', exponent);
        if (!dec_point) {
            /* value is integer, we are just ... */
            if (e_val >= 0) {
                /* adding zeros at the end */
                num_len = exponent + e_val;
                dp_position = num_len; /* decimal point is behind the actual value */
            } else if ((size_t)labs(e_val) < exponent) {
                /* adding decimal point between the integer's digits */
                num_len = exponent + 1;
                dp_position = exponent + e_val;
            } else {
                /* adding decimal point before the integer with adding leading zero(s) */
                num_len = labs(e_val) + 2;
                dp_position = exponent + e_val;
            }
            dp_position -= minus;
        } else {
            /* value is decimal, we are moving the decimal point */
            dp_position = dec_point - in + e_val - minus;
            if (dp_position > (ssize_t)exponent) {
                /* moving decimal point after the decimal value make the integer result */
                num_len = dp_position;
            } else if (dp_position < 0) {
                /* moving decimal point before the decimal value requires additional zero(s)
                 * (decimal point is already count in exponent value) */
                num_len = exponent + labs(dp_position) + 1;
            } else {
                /* moving decimal point just inside the decimal value does not make any change in length */
                num_len = exponent;
            }
        }

        /* allocate buffer for the result (add terminating NULL-byte */
        num = malloc(num_len + 1);
        LY_CHECK_ERR_RET(!num, LOGMEM(jsonctx->ctx), LY_EMEM);

        /* compose the resulting vlaue */
        i = 0;
        if (minus) {
            num[i++] = '-';
        }
        /* add leading zeros */
        if (dp_position <= 0) {
            num[i++] = '0';
            num[i++] = '.';
            for ( ; dp_position; dp_position++) {
                num[i++] = '0';
            }
        }
        /* copy the value */
        ly_bool dp_placed;
        size_t j;
        for (dp_placed = dp_position ? 0 : 1, j = minus; j < exponent; j++) {
            if (in[j] == '.') {
                continue;
            }
            if (!dp_placed) {
                if (!dp_position) {
                    num[i++] = '.';
                    dp_placed = 1;
                } else {
                    dp_position--;
                    if (in[j] == '0') {
                        num_len--;
                        continue;
                    }
                }
            }

            num[i++] = in[j];
        }
        /* trailing zeros */
        while (dp_position--) {
            num[i++] = '0';
        }
        /* terminating NULL byte */
        num[i] = '\0';

        /* store the modified number */
        lyjson_ctx_set_value(jsonctx, num, num_len, 1);
    } else {
        /* store the number */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, offset, 0);
    }
    ly_in_skip(jsonctx->in, offset);

    JSON_PUSH_STATUS_RET(jsonctx, LYJSON_NUMBER);
    LY_CHECK_RET(lyjson_check_next(jsonctx));

    return LY_SUCCESS;
}

static LY_ERR
lyjson_object_name(struct lyjson_ctx *jsonctx)
{
    if (*jsonctx->in->current != '"') {
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON object's member");
        return LY_EVALID;
    }
    ly_in_skip(jsonctx->in, 1);

    LY_CHECK_RET(lyjson_string_(jsonctx));
    LY_CHECK_RET(skip_ws(jsonctx));
    if (*jsonctx->in->current != ':') {
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP,
                LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current, "a JSON object's name-separator ':'");
        return LY_EVALID;
    }
    ly_in_skip(jsonctx->in, 1);
    LY_CHECK_RET(skip_ws(jsonctx));

    return LY_SUCCESS;
}

static LY_ERR
lyjson_object(struct lyjson_ctx *jsonctx)
{
    LY_CHECK_RET(skip_ws(jsonctx));

    if (*jsonctx->in->current == '}') {
        /* empty object */
        ly_in_skip(jsonctx->in, 1);
        lyjson_ctx_set_value(jsonctx, NULL, 0, 0);
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_OBJECT_EMPTY);
        return LY_SUCCESS;
    }

    LY_CHECK_RET(lyjson_object_name(jsonctx));

    /* output data are set by lyjson_string_() */
    JSON_PUSH_STATUS_RET(jsonctx, LYJSON_OBJECT);

    return LY_SUCCESS;
}

/*
 * @brief Process JSON array envelope
 *
 *
 *
 * @param[in] jsonctx JSON parser context
 * @return LY_SUCCESS or LY_EMEM
 */
static LY_ERR
lyjson_array(struct lyjson_ctx *jsonctx)
{
    LY_CHECK_RET(skip_ws(jsonctx));

    if (*jsonctx->in->current == ']') {
        /* empty array */
        ly_in_skip(jsonctx->in, 1);
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_ARRAY_EMPTY);
    } else {
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_ARRAY);
    }

    /* erase previous values, array has no value on its own */
    lyjson_ctx_set_value(jsonctx, NULL, 0, 0);

    return LY_SUCCESS;
}

static LY_ERR
lyjson_value(struct lyjson_ctx *jsonctx)
{
    if (jsonctx->status.count && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
        return LY_SUCCESS;
    }

    if ((*jsonctx->in->current == 'f') && !strncmp(jsonctx->in->current, "false", 5)) {
        /* false */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, 5, 0);
        ly_in_skip(jsonctx->in, 5);
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_FALSE);
        LY_CHECK_RET(lyjson_check_next(jsonctx));

    } else if ((*jsonctx->in->current == 't') && !strncmp(jsonctx->in->current, "true", 4)) {
        /* true */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, 4, 0);
        ly_in_skip(jsonctx->in, 4);
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_TRUE);
        LY_CHECK_RET(lyjson_check_next(jsonctx));

    } else if ((*jsonctx->in->current == 'n') && !strncmp(jsonctx->in->current, "null", 4)) {
        /* none */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, 0, 0);
        ly_in_skip(jsonctx->in, 4);
        JSON_PUSH_STATUS_RET(jsonctx, LYJSON_NULL);
        LY_CHECK_RET(lyjson_check_next(jsonctx));

    } else if (*jsonctx->in->current == '"') {
        /* string */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(lyjson_string(jsonctx));

    } else if (*jsonctx->in->current == '[') {
        /* array */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(lyjson_array(jsonctx));

    } else if (*jsonctx->in->current == '{') {
        /* object */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(lyjson_object(jsonctx));

    } else if ((*jsonctx->in->current == '-') || ((*jsonctx->in->current >= '0') && (*jsonctx->in->current <= '9'))) {
        /* number */
        LY_CHECK_RET(lyjson_number(jsonctx));

    } else {
        /* unexpected value */
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON value");
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

LY_ERR
lyjson_ctx_new(const struct ly_ctx *ctx, struct ly_in *in, struct lyjson_ctx **jsonctx_p)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyjson_ctx *jsonctx;

    assert(ctx);
    assert(in);
    assert(jsonctx_p);

    /* new context */
    jsonctx = calloc(1, sizeof *jsonctx);
    LY_CHECK_ERR_RET(!jsonctx, LOGMEM(ctx), LY_EMEM);
    jsonctx->ctx = ctx;
    jsonctx->line = 1;
    jsonctx->in = in;

    /* parse JSON value, if any */
    LY_CHECK_GOTO(ret = skip_ws(jsonctx), cleanup);
    if (lyjson_ctx_status(jsonctx, 0) == LYJSON_END) {
        /* empty data input */
        goto cleanup;
    }

    ret = lyjson_value(jsonctx);

    if ((jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
        ret = LY_EVALID;
    }

cleanup:
    if (ret) {
        lyjson_ctx_free(jsonctx);
    } else {
        *jsonctx_p = jsonctx;
    }
    return ret;
}

void
lyjson_ctx_backup(struct lyjson_ctx *jsonctx)
{
    if (jsonctx->backup.dynamic) {
        free((char *)jsonctx->backup.value);
    }
    jsonctx->backup.status = lyjson_ctx_status(jsonctx, 0);
    jsonctx->backup.status_count = jsonctx->status.count;
    jsonctx->backup.value = jsonctx->value;
    jsonctx->backup.value_len = jsonctx->value_len;
    jsonctx->backup.input = jsonctx->in->current;
    jsonctx->backup.dynamic = jsonctx->dynamic;
    jsonctx->dynamic = 0;
}

void
lyjson_ctx_restore(struct lyjson_ctx *jsonctx)
{
    if (jsonctx->dynamic) {
        free((char *)jsonctx->value);
    }
    jsonctx->status.count = jsonctx->backup.status_count;
    jsonctx->status.objs[jsonctx->backup.status_count - 1] = (void *)jsonctx->backup.status;
    jsonctx->value = jsonctx->backup.value;
    jsonctx->value_len = jsonctx->backup.value_len;
    jsonctx->in->current = jsonctx->backup.input;
    jsonctx->dynamic = jsonctx->backup.dynamic;
    jsonctx->backup.dynamic = 0;
}

LY_ERR
lyjson_ctx_next(struct lyjson_ctx *jsonctx, enum LYJSON_PARSER_STATUS *status)
{
    LY_ERR ret = LY_SUCCESS;
    ly_bool toplevel = 0;
    enum LYJSON_PARSER_STATUS prev;

    assert(jsonctx);

    prev = lyjson_ctx_status(jsonctx, 0);

    if ((prev == LYJSON_OBJECT) || (prev == LYJSON_ARRAY)) {
        /* get value for the object's member OR the first value in the array */
        ret = lyjson_value(jsonctx);
        goto result;
    } else {
        /* the previous token is closed and should be completely processed */
        JSON_POP_STATUS_RET(jsonctx);
        prev = lyjson_ctx_status(jsonctx, 0);
    }

    if (!jsonctx->status.count) {
        /* we are done with the top level value */
        toplevel = 1;
    }
    LY_CHECK_RET(skip_ws(jsonctx));
    if (toplevel && !jsonctx->status.count) {
        /* EOF expected, but there are some data after the top level token */
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
                "Expecting end-of-input, but some data follows the top level JSON value.");
        return LY_EVALID;
    }

    if (toplevel) {
        /* we are done */
        return LY_SUCCESS;
    }

    /* continue with the next token */
    assert(prev == LYJSON_OBJECT || prev == LYJSON_ARRAY);

    if (*jsonctx->in->current == ',') {
        /* sibling item in the ... */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(skip_ws(jsonctx));

        if (prev == LYJSON_OBJECT) {
            /* ... object - get another object's member */
            ret = lyjson_object_name(jsonctx);
        } else { /* LYJSON_ARRAY */
            /* ... array - get another complete value */
            ret = lyjson_value(jsonctx);
        }
    } else if (((prev == LYJSON_OBJECT) && (*jsonctx->in->current == '}')) || ((prev == LYJSON_ARRAY) && (*jsonctx->in->current == ']'))) {
        ly_in_skip(jsonctx->in, 1);
        JSON_POP_STATUS_RET(jsonctx);
        JSON_PUSH_STATUS_RET(jsonctx, prev + 1);
    } else {
        /* unexpected value */
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, prev == LYJSON_ARRAY ? "another JSON value in array" : "another JSON object's member");
        return LY_EVALID;
    }

result:
    if ((ret == LY_SUCCESS) && (jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
        ret = LY_EVALID;
    }

    if ((ret == LY_SUCCESS) && status) {
        *status = lyjson_ctx_status(jsonctx, 0);
    }

    return ret;
}

enum LYJSON_PARSER_STATUS
lyjson_ctx_status(struct lyjson_ctx *jsonctx, uint32_t index)
{
    assert(jsonctx);

    if (jsonctx->status.count < index) {
        return LYJSON_ERROR;
    } else if (jsonctx->status.count == index) {
        return LYJSON_ROOT;
    } else {
        return (enum LYJSON_PARSER_STATUS)(uintptr_t)jsonctx->status.objs[jsonctx->status.count - (index + 1)];
    }
}

void
lyjson_ctx_free(struct lyjson_ctx *jsonctx)
{
    if (!jsonctx) {
        return;
    }

    if (jsonctx->dynamic) {
        free((char *)jsonctx->value);
    }
    if (jsonctx->backup.dynamic) {
        free((char *)jsonctx->backup.value);
    }

    ly_set_erase(&jsonctx->status, NULL);

    free(jsonctx);
}
