/**
 * @file json.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief Generic JSON format parser for libyang
 *
 * Copyright (c) 2020 - 2023 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 <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "in_internal.h"
#include "json.h"
#include "ly_common.h"
#include "tree_schema_internal.h"

const char *
lyjson_token2str(enum LYJSON_PARSER_STATUS status)
{
    switch (status) {
    case LYJSON_ERROR:
        return "error";
    case LYJSON_OBJECT:
        return "object";
    case LYJSON_OBJECT_NEXT:
        return "object next";
    case LYJSON_OBJECT_CLOSED:
        return "object closed";
    case LYJSON_ARRAY:
        return "array";
    case LYJSON_ARRAY_NEXT:
        return "array next";
    case LYJSON_ARRAY_CLOSED:
        return "array closed";
    case LYJSON_OBJECT_NAME:
        return "object name";
    case LYJSON_NUMBER:
        return "number";
    case LYJSON_STRING:
        return "string";
    case LYJSON_TRUE:
        return "true";
    case LYJSON_FALSE:
        return "false";
    case LYJSON_NULL:
        return "null";
    case LYJSON_END:
        return "end of input";
    }

    return "";
}

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

    if (!jsonctx->status.count) {
        return LYJSON_END;
    }

    return (enum LYJSON_PARSER_STATUS)(uintptr_t)jsonctx->status.objs[jsonctx->status.count - 1];
}

uint32_t
lyjson_ctx_depth(struct lyjson_ctx *jsonctx)
{
    return jsonctx->status.count;
}

/**
 * @brief Skip WS in the JSON context.
 *
 * @param[in] jsonctx JSON parser context.
 */
static void
lyjson_skip_ws(struct lyjson_ctx *jsonctx)
{
    /* skip whitespaces */
    while (is_jsonws(*jsonctx->in->current)) {
        if (*jsonctx->in->current == '\n') {
            LY_IN_NEW_LINE(jsonctx->in);
        }
        ly_in_skip(jsonctx->in, 1);
    }
}

/**
 * @brief Set value in the JSON context.
 *
 * @param[in] jsonctx JSON parser context.
 * @param[in] value Value to set.
 * @param[in] value_len Length of @p value.
 * @param[in] dynamic Whether @p value is dynamically-allocated.
 */
static void
lyjson_ctx_set_value(struct lyjson_ctx *jsonctx, const char *value, size_t value_len, ly_bool dynamic)
{
    assert(jsonctx);

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

/**
 * @brief Parse a JSON string (starting after double quotes) and store it in the context.
 *
 * @param[in] jsonctx JSON parser context.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_string(struct lyjson_ctx *jsonctx)
{
    const char *in = jsonctx->in->current, *start, *c;
    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, orig_line;
    uint32_t value;
    uint8_t i;

    assert(jsonctx);

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

    /* parse */
    while (in[offset]) {
        switch (in[offset]) {
        case '\\':
            /* escape sequence */
            c = &in[offset];
            if (!buf) {
                /* prepare output buffer */
                buf = malloc(LYJSON_STRING_BUF_START);
                LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                size = LYJSON_STRING_BUF_START;
            }

            /* 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) {
                size_t increment;

                for (increment = LYJSON_STRING_BUF_STEP; len + offset + 4 >= size + increment; increment += LYJSON_STRING_BUF_STEP) {}
                buf = ly_realloc(buf, size + increment);
                LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                size += LYJSON_STRING_BUF_STEP;
            }

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

            i = 1;
            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 (!in[offset + i]) {
                        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid basic multilingual plane character \"%s\".", c);
                        goto error;
                    } else if (isdigit(in[offset + i])) {
                        u = (in[offset + i] - '0');
                    } else if (in[offset + i] > 'F') {
                        u = LY_BASE_DEC + (in[offset + i] - 'a');
                    } else {
                        u = LY_BASE_DEC + (in[offset + i] - 'A');
                    }
                    value = (LY_BASE_HEX * value) + u;
                }
                break;
            default:
                /* invalid escape sequence */
                LOGVAL(jsonctx->ctx, 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, LYVE_SYNTAX, "Invalid character reference \"%.*s\" (0x%08" PRIx32 ").",
                    (int)(&in[offset] - c), c, 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 */
            break;

        case '"':
            /* 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;
                if (offset) {
                    memcpy(&buf[len], in, offset);
                }

                /* set terminating NULL byte */
                buf[len + offset] = '\0';
            }
            len += offset;
            ++offset;
            in += offset;
            goto success;

        default:
            /* get it as UTF-8 character for check */
            c = &in[offset];
            LY_CHECK_ERR_GOTO(ly_getutf8(&c, &value, &u),
                    LOGVAL(jsonctx->ctx, LY_VCODE_INCHAR, in[offset]), error);

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

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

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

error:
    free(buf);
    return LY_EVALID;

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

    return LY_SUCCESS;
}

/**
 * @brief Calculate how many @p c characters there are in a row.
 *
 * @param[in] str Count from this position.
 * @param[in] end Position after the last checked character.
 * @param[in] c Checked character.
 * @param[in] backwards Set to 1, if to proceed from end-1 to str.
 * @return Number of characters in a row.
 */
static uint32_t
lyjson_count_in_row(const char *str, const char *end, char c, ly_bool backwards)
{
    uint32_t cnt;

    assert(str && end);

    if (str >= end) {
        return 0;
    }

    if (!backwards) {
        for (cnt = 0; (str != end) && (*str == c); ++str, ++cnt) {}
    } else {
        --end;
        --str;
        for (cnt = 0; (str != end) && (*end == c); --end, ++cnt) {}
    }

    return cnt;
}

/**
 * @brief Check if the number can be shortened to zero.
 *
 * @param[in] in Start of input string;
 * @param[in] end End of input string;
 * @return 1 if number is zero, otherwise 0.
 */
static ly_bool
lyjson_number_is_zero(const char *in, const char *end)
{
    assert(in < end);

    if ((in[0] == '-') || (in[0] == '+')) {
        in++;
        assert(in < end);
    }
    if ((in[0] == '0') && (in[1] == '.')) {
        in += 2;
        if (!(in < end)) {
            return 1;
        }
    }

    return lyjson_count_in_row(in, end, '0', 0) == (uint32_t)(end - in);
}

/**
 * @brief Allocate buffer for number in string format.
 *
 * @param[in] jsonctx JSON context.
 * @param[in] num_len Required space in bytes for a number.
 * Terminating null byte is added by default.
 * @param[out] buffer Output allocated buffer.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_get_buffer_for_number(const struct ly_ctx *ctx, uint64_t num_len, char **buffer)
{
    *buffer = NULL;

    LY_CHECK_ERR_RET((num_len + 1) > LY_NUMBER_MAXLEN, LOGVAL(ctx, LYVE_SEMANTICS,
            "Number encoded as a string exceeded the LY_NUMBER_MAXLEN limit."), LY_EVALID);

    /* allocate buffer for the result (add NULL-byte) */
    *buffer = malloc(num_len + 1);
    LY_CHECK_ERR_RET(!(*buffer), LOGMEM(ctx), LY_EMEM);
    return LY_SUCCESS;
}

/**
 * @brief Copy the 'numeric part' (@p num) except its decimal point
 * (@p dec_point) and insert the new decimal point (@p dp_position)
 * only if it is to be placed in the 'numeric part' range (@p num).
 *
 * @param[in] num Begin of the 'numeric part'.
 * @param[in] num_len Length of the 'numeric part'.
 * @param[in] dec_point Pointer to the old decimal point.
 * If it has a NULL value, it is ignored.
 * @param[in] dp_position Position of the new decimal point.
 * If it has a negative value, it is ignored.
 * @param[out] dst Memory into which the copied result is written.
 * @return Number of characters written to the @p dst.
 */
static uint32_t
lyjson_exp_number_copy_num_part(const char *num, uint32_t num_len, char *dec_point, int32_t dp_position, char *dst)
{
    int32_t dec_point_idx;
    int32_t n, d;

    assert(num && dst);

    dec_point_idx = dec_point ? dec_point - num : INT32_MAX;
    assert((dec_point_idx >= 0) && (dec_point_idx != dp_position));

    for (n = 0, d = 0; (uint32_t)n < num_len; n++) {
        if (n == dec_point_idx) {
            continue;
        } else if (d == dp_position) {
            dst[d++] = '.';
            dst[d++] = num[n];
        } else {
            dst[d++] = num[n];
        }
    }

    return d;
}

/**
 * @brief Convert JSON number with exponent into the representation
 * used by YANG.
 *
 * The input numeric string must be syntactically valid. Also, before
 * calling this function, checks should be performed using the
 * ::lyjson_number_is_zero().
 *
 * @param[in] ctx Context for the error message.
 * @param[in] in Beginning of the string containing the number.
 * @param[in] exponent Pointer to the letter E/e.
 * @param[in] total_len Total size of the input number.
 * @param[out] res Conversion result.
 * @param[out] res_len Length of the result.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_exp_number(const struct ly_ctx *ctx, const char *in, const char *exponent, uint64_t total_len, char **res,
        size_t *res_len)
{

#define MAYBE_WRITE_MINUS(ARRAY, INDEX, FLAG) \
        if (FLAG) { \
            ARRAY[INDEX++] = '-'; \
        }

/* Length of leading zero followed by the decimal point. */
#define LEADING_ZERO 1

/* Flags for the ::lyjson_count_in_row() */
#define FORWARD 0
#define BACKWARD 1

    /* Buffer where the result is stored. */
    char *buf;
    /* Size without space for terminating NULL-byte. */
    uint64_t buf_len;
    /* Index to buf. */
    uint32_t i = 0;
    /* A 'numeric part' doesn't contain a minus sign or an leading zero.
     * For example, in 0.45, there is the leading zero.
     */
    const char *num;
    /* Length of the 'numeric part' ends before E/e. */
    uint16_t num_len;
    /* Position of decimal point in the num. */
    char *dec_point;
    /* Final position of decimal point in the buf. */
    int32_t dp_position;
    /* Exponent as integer. */
    long long e_val;
    /* Byte for the decimal point. */
    int8_t dot;
    /* Required additional byte for the minus sign. */
    uint8_t minus;
    /* The number of zeros. */
    long zeros;
    /* If the number starts with leading zero followed by the decimal point. */
    ly_bool leading_zero;

    assert(ctx && in && exponent && res && res_len && (total_len > 2));
    assert((in < exponent) && ((*exponent == 'e') || (*exponent == 'E')));

    if ((exponent - in) > UINT16_MAX) {
        LOGVAL(ctx, LYVE_SEMANTICS, "JSON number is too long.");
        return LY_EVALID;
    }

    /* Convert exponent. */
    errno = 0;
    e_val = strtoll(exponent + 1, NULL, LY_BASE_DEC);
    if (errno || (e_val > UINT16_MAX) || (e_val < -UINT16_MAX)) {
        LOGVAL(ctx, LYVE_SEMANTICS,
                "Exponent out-of-bounds in a JSON Number value (%.*s).",
                (int)total_len, in);
        return LY_EVALID;
    }

    minus = in[0] == '-';
    if (in[minus] == '0') {
        assert(in[minus + 1] == '.');
        leading_zero = 1;
        /* The leading zero has been found, it will be skipped. */
        num = &in[minus + 1];
    } else {
        leading_zero = 0;
        /* Set to the first number. */
        num = &in[minus];
    }
    num_len = exponent - num;

    /* Find the location of the decimal points. */
    dec_point = ly_strnchr(num, '.', num_len);
    dp_position = dec_point ?
            dec_point - num + e_val :
            num_len + e_val;

    /* Remove zeros after the decimal point from the end of
     * the 'numeric part' because these are useless.
     * (For example, in 40.001000 these are the last 3).
     */
    num_len -= dp_position > 0 ?
            lyjson_count_in_row(num + dp_position - 1, exponent, '0', BACKWARD) :
            lyjson_count_in_row(num, exponent, '0', BACKWARD);

    /* Decide what to do with the dot from the 'numeric part'. */
    if (dec_point && ((int32_t)(num_len - 1) == dp_position)) {
        /* Decimal point in the last place is useless. */
        dot = -1;
    } else if (dec_point) {
        /* Decimal point is shifted. */
        dot = 0;
    } else {
        /* Additional byte for the decimal point is requred. */
        dot = 1;
    }

    /* Final composition of the result. */
    if (dp_position <= 0) {
        /* Adding decimal point before the integer with adding additional zero(s). */

        zeros = labs(dp_position);
        buf_len = minus + LEADING_ZERO + dot + zeros + num_len;
        LY_CHECK_RET(lyjson_get_buffer_for_number(ctx, buf_len, &buf));
        MAYBE_WRITE_MINUS(buf, i, minus);
        buf[i++] = '0';
        buf[i++] = '.';
        memset(buf + i, '0', zeros);
        i += zeros;
        dp_position = -1;
        lyjson_exp_number_copy_num_part(num, num_len, dec_point, dp_position, buf + i);
    } else if (leading_zero && (dp_position < (ssize_t)num_len)) {
        /* Insert decimal point between the integer's digits. */

        /* Set a new range of 'numeric part'. Old decimal point is skipped. */
        num++;
        num_len--;
        dp_position--;
        /* Get the number of useless zeros between the old
         * and new decimal point. For example, in the number 0.005E1,
         * there is one useless zero.
         */
        zeros = lyjson_count_in_row(num, num + dp_position + 1, '0', FORWARD);
        /* If the new decimal point will be in the place of the first non-zero subnumber. */
        if (zeros == (dp_position + 1)) {
            /* keep one zero as leading zero */
            zeros--;
            /* new decimal point will be behind the leading zero */
            dp_position = 1;
            dot = 1;
        } else {
            dot = 0;
        }
        buf_len = minus + dot + (num_len - zeros);
        LY_CHECK_RET(lyjson_get_buffer_for_number(ctx, buf_len, &buf));
        MAYBE_WRITE_MINUS(buf, i, minus);
        /* Skip useless zeros and copy. */
        lyjson_exp_number_copy_num_part(num + zeros, num_len - zeros, NULL, dp_position, buf + i);
    } else if (dp_position < (ssize_t)num_len) {
        /* Insert decimal point between the integer's digits. */

        buf_len = minus + dot + num_len;
        LY_CHECK_RET(lyjson_get_buffer_for_number(ctx, buf_len, &buf));
        MAYBE_WRITE_MINUS(buf, i, minus);
        lyjson_exp_number_copy_num_part(num, num_len, dec_point, dp_position, buf + i);
    } else if (leading_zero) {
        /* Adding decimal point after the decimal value make the integer result. */

        /* Set a new range of 'numeric part'. Old decimal point is skipped. */
        num++;
        num_len--;
        /* Get the number of useless zeros. */
        zeros = lyjson_count_in_row(num, num + num_len, '0', FORWARD);
        buf_len = minus + dp_position - zeros;
        LY_CHECK_RET(lyjson_get_buffer_for_number(ctx, buf_len, &buf));
        MAYBE_WRITE_MINUS(buf, i, minus);
        /* Skip useless zeros and copy. */
        i += lyjson_exp_number_copy_num_part(num + zeros, num_len - zeros, NULL, dp_position, buf + i);
        /* Add multiples of ten behind the 'numeric part'. */
        memset(buf + i, '0', buf_len - i);
    } else {
        /* Adding decimal point after the decimal value make the integer result. */

        buf_len = minus + dp_position;
        LY_CHECK_RET(lyjson_get_buffer_for_number(ctx, buf_len, &buf));
        MAYBE_WRITE_MINUS(buf, i, minus);
        i += lyjson_exp_number_copy_num_part(num, num_len, dec_point, dp_position, buf + i);
        /* Add multiples of ten behind the 'numeric part'. */
        memset(buf + i, '0', buf_len - i);
    }

    buf[buf_len] = '\0';
    *res = buf;
    *res_len = buf_len;

#undef MAYBE_WRITE_MINUS
#undef LEADING_ZERO
#undef FORWARD
#undef BACKWARD

    return LY_SUCCESS;
}

/**
 * @brief Parse a JSON number and store it in the context.
 *
 * @param[in] jsonctx JSON parser context.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_number(struct lyjson_ctx *jsonctx)
{
    size_t offset = 0, num_len;
    const char *in = jsonctx->in->current, *exponent = NULL;
    uint8_t minus = 0;
    char *num;

    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, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
        } else {
            LOGVAL(jsonctx->ctx, 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 = &in[offset];
        ++offset;
        if ((in[offset] == '+') || (in[offset] == '-')) {
            ++offset;
        }
        if (!isdigit(in[offset])) {
            goto invalid_character;
        }
        while (isdigit(in[offset])) {
            ++offset;
        }
    }

    if (lyjson_number_is_zero(in, exponent ? exponent : &in[offset])) {
        lyjson_ctx_set_value(jsonctx, in, minus + 1, 0);
    } else if (exponent && lyjson_number_is_zero(exponent + 1, &in[offset])) {
        lyjson_ctx_set_value(jsonctx, in, exponent - in, 0);
    } else if (exponent) {
        LY_CHECK_RET(lyjson_exp_number(jsonctx->ctx, in, exponent, offset, &num, &num_len));
        lyjson_ctx_set_value(jsonctx, num, num_len, 1);
    } else {
        if (offset > LY_NUMBER_MAXLEN) {
            LOGVAL(jsonctx->ctx, LYVE_SEMANTICS,
                    "Number encoded as a string exceeded the LY_NUMBER_MAXLEN limit.");
            return LY_EVALID;
        }
        lyjson_ctx_set_value(jsonctx, in, offset, 0);
    }
    ly_in_skip(jsonctx->in, offset);

    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 && in && jsonctx_p);

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

    /* input line logging */
    ly_log_location(NULL, NULL, NULL, in);

    /* WS are always expected to be skipped */
    lyjson_skip_ws(jsonctx);

    if (jsonctx->in->current[0] == '\0') {
        /* empty file, invalid */
        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Empty JSON file.");
        ret = LY_EVALID;
        goto cleanup;
    }

    /* start JSON parsing */
    LY_CHECK_GOTO(ret = lyjson_ctx_next(jsonctx, NULL), cleanup);

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

/**
 * @brief Parse next JSON token, object-name is expected.
 *
 * @param[in] jsonctx JSON parser context.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_next_object_name(struct lyjson_ctx *jsonctx)
{
    switch (*jsonctx->in->current) {
    case '\0':
        /* EOF */
        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
        return LY_EVALID;

    case '"':
        /* object name */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(lyjson_string(jsonctx));
        lyjson_skip_ws(jsonctx);

        if (*jsonctx->in->current != ':') {
            LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current,
                    "a JSON value name-separator ':'");
            return LY_EVALID;
        }
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_OBJECT_NAME);
        break;

    case '}':
        /* object end */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_OBJECT_CLOSED);
        break;

    default:
        /* unexpected value */
        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON object name");
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

/**
 * @brief Parse next JSON token, value is expected.
 *
 * @param[in] jsonctx JSON parser context.
 * @param[in] array_end Whether array-end is accepted or not.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_next_value(struct lyjson_ctx *jsonctx, ly_bool array_end)
{
    switch (*jsonctx->in->current) {
    case '\0':
        /* EOF */
        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
        return LY_EVALID;

    case '"':
        /* string */
        ly_in_skip(jsonctx->in, 1);
        LY_CHECK_RET(lyjson_string(jsonctx));
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_STRING);
        break;

    case '-':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        /* number */
        LY_CHECK_RET(lyjson_number(jsonctx));
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_NUMBER);
        break;

    case '{':
        /* object */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_OBJECT);
        break;

    case '[':
        /* array */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_ARRAY);
        break;

    case 't':
        if (strncmp(jsonctx->in->current + 1, "rue", ly_strlen_const("rue"))) {
            goto unexpected_value;
        }

        /* true */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, ly_strlen_const("true"), 0);
        ly_in_skip(jsonctx->in, ly_strlen_const("true"));
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_TRUE);
        break;

    case 'f':
        if (strncmp(jsonctx->in->current + 1, "alse", ly_strlen_const("alse"))) {
            goto unexpected_value;
        }

        /* false */
        lyjson_ctx_set_value(jsonctx, jsonctx->in->current, ly_strlen_const("false"), 0);
        ly_in_skip(jsonctx->in, ly_strlen_const("false"));
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_FALSE);
        break;

    case 'n':
        if (strncmp(jsonctx->in->current + 1, "ull", ly_strlen_const("ull"))) {
            goto unexpected_value;
        }

        /* null */
        lyjson_ctx_set_value(jsonctx, "", 0, 0);
        ly_in_skip(jsonctx->in, ly_strlen_const("null"));
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_NULL);
        break;

    case ']':
        if (!array_end) {
            goto unexpected_value;
        }

        /* array end */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_ARRAY_CLOSED);
        break;

    default:
unexpected_value:
        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON value");
        return LY_EVALID;
    }

    if (jsonctx->status.count > LY_MAX_BLOCK_DEPTH * 10) {
        LOGERR(jsonctx->ctx, LY_EINVAL, "Maximum number %d of nestings has been exceeded.", LY_MAX_BLOCK_DEPTH * 10);
        return LY_EINVAL;
    }

    return LY_SUCCESS;
}

/**
 * @brief Parse next JSON token, object-next-item is expected.
 *
 * @param[in] jsonctx JSON parser context.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_next_object_item(struct lyjson_ctx *jsonctx)
{
    switch (*jsonctx->in->current) {
    case '\0':
        /* EOF */
        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
        return LY_EVALID;

    case '}':
        /* object end */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_OBJECT_CLOSED);
        break;

    case ',':
        /* next object item */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_OBJECT_NEXT);
        break;

    default:
        /* unexpected value */
        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON object-end or next item");
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

/**
 * @brief Parse next JSON token, array-next-item is expected.
 *
 * @param[in] jsonctx JSON parser context.
 * @return LY_ERR value.
 */
static LY_ERR
lyjson_next_array_item(struct lyjson_ctx *jsonctx)
{
    switch (*jsonctx->in->current) {
    case '\0':
        /* EOF */
        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
        return LY_EVALID;

    case ']':
        /* array end */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_ARRAY_CLOSED);
        break;

    case ',':
        /* next array item */
        ly_in_skip(jsonctx->in, 1);
        LYJSON_STATUS_PUSH_RET(jsonctx, LYJSON_ARRAY_NEXT);
        break;

    default:
        /* unexpected value */
        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                jsonctx->in->current, "a JSON array-end or next item");
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

LY_ERR
lyjson_ctx_next(struct lyjson_ctx *jsonctx, enum LYJSON_PARSER_STATUS *status)
{
    LY_ERR ret = LY_SUCCESS;
    enum LYJSON_PARSER_STATUS cur;

    assert(jsonctx);

    cur = lyjson_ctx_status(jsonctx);
    switch (cur) {
    case LYJSON_OBJECT:
        LY_CHECK_GOTO(ret = lyjson_next_object_name(jsonctx), cleanup);
        break;
    case LYJSON_ARRAY:
        LY_CHECK_GOTO(ret = lyjson_next_value(jsonctx, 1), cleanup);
        break;
    case LYJSON_OBJECT_NEXT:
        LYJSON_STATUS_POP(jsonctx);
        LY_CHECK_GOTO(ret = lyjson_next_object_name(jsonctx), cleanup);
        break;
    case LYJSON_ARRAY_NEXT:
        LYJSON_STATUS_POP(jsonctx);
        LY_CHECK_GOTO(ret = lyjson_next_value(jsonctx, 0), cleanup);
        break;
    case LYJSON_OBJECT_NAME:
        lyjson_ctx_set_value(jsonctx, NULL, 0, 0);
        LYJSON_STATUS_POP(jsonctx);
        LY_CHECK_GOTO(ret = lyjson_next_value(jsonctx, 0), cleanup);
        break;
    case LYJSON_OBJECT_CLOSED:
    case LYJSON_ARRAY_CLOSED:
        LYJSON_STATUS_POP(jsonctx);
    /* fallthrough */
    case LYJSON_NUMBER:
    case LYJSON_STRING:
    case LYJSON_TRUE:
    case LYJSON_FALSE:
    case LYJSON_NULL:
        lyjson_ctx_set_value(jsonctx, NULL, 0, 0);
        LYJSON_STATUS_POP(jsonctx);
        cur = lyjson_ctx_status(jsonctx);

        if (cur == LYJSON_OBJECT) {
            LY_CHECK_GOTO(ret = lyjson_next_object_item(jsonctx), cleanup);
            break;
        } else if (cur == LYJSON_ARRAY) {
            LY_CHECK_GOTO(ret = lyjson_next_array_item(jsonctx), cleanup);
            break;
        }

        assert(cur == LYJSON_END);
        goto cleanup;
    case LYJSON_END:
        LY_CHECK_GOTO(ret = lyjson_next_value(jsonctx, 0), cleanup);
        break;
    case LYJSON_ERROR:
        LOGINT(jsonctx->ctx);
        ret = LY_EINT;
        goto cleanup;
    }

    /* skip WS */
    lyjson_skip_ws(jsonctx);

cleanup:
    if (!ret && status) {
        *status = lyjson_ctx_status(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);
    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;
}

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

    ly_log_location_revert(0, 0, 0, 1);

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

    ly_set_erase(&jsonctx->status, NULL);

    free(jsonctx);
}
