/**
 * @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;
    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);
    LOGVAL_LINE(jsonctx->ctx, start_line, LYVE_SYNTAX, "Missing quotation-mark at the end of a JSON string.");

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;

    LOG_LOCSET(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;
    }

    LOG_LOCBACK(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);
}
