/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * json.c: Encoding and decoding JSON.
 *
 * Follows this standard: https://tools.ietf.org/html/rfc7159.html
 */

#include "vim.h"

#if defined(FEAT_EVAL) || defined(PROTO)
static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none);
static int json_decode_item(js_read_T *reader, typval_T *res);

/*
 * Encode "val" into a JSON format string.
 */
    char_u *
json_encode(typval_T *val)
{
    garray_T ga;

    /* Store bytes in the growarray. */
    ga_init2(&ga, 1, 4000);
    json_encode_item(&ga, val, get_copyID(), TRUE);
    return ga.ga_data;
}

/*
 * Encode ["nr", "val"] into a JSON format string.
 * Returns NULL when out of memory.
 */
    char_u *
json_encode_nr_expr(int nr, typval_T *val)
{
    typval_T	listtv;
    typval_T	nrtv;
    char_u	*text;

    nrtv.v_type = VAR_NUMBER;
    nrtv.vval.v_number = nr;
    if (rettv_list_alloc(&listtv) == FAIL)
	return NULL;
    if (list_append_tv(listtv.vval.v_list, &nrtv) == FAIL
	    || list_append_tv(listtv.vval.v_list, val) == FAIL)
    {
	list_unref(listtv.vval.v_list);
	return NULL;
    }

    text = json_encode(&listtv);
    list_unref(listtv.vval.v_list);
    return text;
}

    static void
write_string(garray_T *gap, char_u *str)
{
    char_u	*res = str;
    char_u	numbuf[NUMBUFLEN];

    if (res == NULL)
	ga_concat(gap, (char_u *)"null");
    else
    {
	ga_append(gap, '"');
	while (*res != NUL)
	{
	    int c = PTR2CHAR(res);

	    switch (c)
	    {
		case 0x08:
		    ga_append(gap, '\\'); ga_append(gap, 'b'); break;
		case 0x09:
		    ga_append(gap, '\\'); ga_append(gap, 't'); break;
		case 0x0a:
		    ga_append(gap, '\\'); ga_append(gap, 'n'); break;
		case 0x0c:
		    ga_append(gap, '\\'); ga_append(gap, 'f'); break;
		case 0x0d:
		    ga_append(gap, '\\'); ga_append(gap, 'r'); break;
		case 0x22: /* " */
		case 0x5c: /* \ */
		    ga_append(gap, '\\');
		    ga_append(gap, c);
		    break;
		default:
		    if (c >= 0x20)
		    {
#ifdef FEAT_MBYTE
			numbuf[mb_char2bytes(c, numbuf)] = NUL;
#else
			numbuf[0] = c;
			numbuf[1] = NUL;
#endif
			ga_concat(gap, numbuf);
		    }
		    else
		    {
			vim_snprintf((char *)numbuf, NUMBUFLEN,
							 "\\u%04lx", (long)c);
			ga_concat(gap, numbuf);
		    }
	    }
	    mb_cptr_adv(res);
	}
	ga_append(gap, '"');
    }
}

/*
 * Encode "val" into "gap".
 * Return FAIL or OK.
 */
    static int
json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none)
{
    char_u	numbuf[NUMBUFLEN];
    char_u	*res;
    list_T	*l;
    dict_T	*d;

    switch (val->v_type)
    {
	case VAR_SPECIAL:
	    switch (val->vval.v_number)
	    {
		case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
		case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
		case VVAL_NONE: if (!allow_none)
				    /* TODO: better error */
				    EMSG(_(e_invarg));
				break;
		case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
	    }
	    break;

	case VAR_NUMBER:
	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%ld",
						    (long)val->vval.v_number);
	    ga_concat(gap, numbuf);
	    break;

	case VAR_STRING:
	    res = val->vval.v_string;
	    write_string(gap, res);
	    break;

	case VAR_FUNC:
	    /* no JSON equivalent TODO: better error */
	    EMSG(_(e_invarg));
	    return FAIL;

	case VAR_LIST:
	    l = val->vval.v_list;
	    if (l == NULL)
		ga_concat(gap, (char_u *)"null");
	    else
	    {
		if (l->lv_copyID == copyID)
		    ga_concat(gap, (char_u *)"[]");
		else
		{
		    listitem_T	*li;

		    l->lv_copyID = copyID;
		    ga_append(gap, '[');
		    for (li = l->lv_first; li != NULL && !got_int; )
		    {
			if (json_encode_item(gap, &li->li_tv, copyID, TRUE)
								      == FAIL)
			    return FAIL;
			li = li->li_next;
			if (li != NULL)
			    ga_append(gap, ',');
		    }
		    ga_append(gap, ']');
		    l->lv_copyID = 0;
		}
	    }
	    break;

	case VAR_DICT:
	    d = val->vval.v_dict;
	    if (d == NULL)
		ga_concat(gap, (char_u *)"null");
	    else
	    {
		if (d->dv_copyID == copyID)
		    ga_concat(gap, (char_u *)"{}");
		else
		{
		    int		first = TRUE;
		    int		todo = (int)d->dv_hashtab.ht_used;
		    hashitem_T	*hi;

		    d->dv_copyID = copyID;
		    ga_append(gap, '{');

		    for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int;
									 ++hi)
			if (!HASHITEM_EMPTY(hi))
			{
			    --todo;
			    if (first)
				first = FALSE;
			    else
				ga_append(gap, ',');
			    write_string(gap, hi->hi_key);
			    ga_append(gap, ':');
			    if (json_encode_item(gap, &dict_lookup(hi)->di_tv,
						       copyID, FALSE) == FAIL)
				return FAIL;
			}
		    ga_append(gap, '}');
		    d->dv_copyID = 0;
		}
	    }
	    break;

#ifdef FEAT_FLOAT
	case VAR_FLOAT:
	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
	    ga_concat(gap, numbuf);
	    break;
#endif
	default: EMSG2(_(e_intern2), "json_encode_item()"); break;
		 return FAIL;
    }
    return OK;
}

/*
 * When "reader" has less than NUMBUFLEN bytes available, call the fill
 * callback to get more.
 */
    static void
fill_numbuflen(js_read_T *reader)
{
    if (reader->js_fill != NULL && (int)(reader->js_end - reader->js_buf)
						- reader->js_used < NUMBUFLEN)
    {
	if (reader->js_fill(reader))
	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    }
}

/*
 * Skip white space in "reader".
 * Also tops up readahead when needed.
 */
    static void
json_skip_white(js_read_T *reader)
{
    int c;

    for (;;)
    {
	c = reader->js_buf[reader->js_used];
	if (reader->js_fill != NULL && c == NUL)
	{
	    if (reader->js_fill(reader))
		reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
	    continue;
	}
	if (c != ' ' && c != TAB && c != NL && c != CAR)
	    break;
	++reader->js_used;
    }
    fill_numbuflen(reader);
}

    static int
json_decode_array(js_read_T *reader, typval_T *res)
{
    char_u	*p;
    typval_T	item;
    listitem_T	*li;
    int		ret;

    if (res != NULL && rettv_list_alloc(res) == FAIL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	return FAIL;
    }
    ++reader->js_used; /* consume the '[' */

    while (TRUE)
    {
	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == NUL)
	    return MAYBE;
	if (*p == ']')
	{
	    ++reader->js_used; /* consume the ']' */
	    break;
	}

	ret = json_decode_item(reader, res == NULL ? NULL : &item);
	if (ret != OK)
	    return ret;
	if (res != NULL)
	{
	    li = listitem_alloc();
	    if (li == NULL)
	    {
		clear_tv(&item);
		return FAIL;
	    }
	    li->li_tv = item;
	    list_append(res->vval.v_list, li);
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == ',')
	    ++reader->js_used;
	else if (*p != ']')
	{
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
    }
    return OK;
}

    static int
json_decode_object(js_read_T *reader, typval_T *res)
{
    char_u	*p;
    typval_T	tvkey;
    typval_T	item;
    dictitem_T	*di;
    char_u	buf[NUMBUFLEN];
    char_u	*key = NULL;
    int		ret;

    if (res != NULL && rettv_dict_alloc(res) == FAIL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	return FAIL;
    }
    ++reader->js_used; /* consume the '{' */

    while (TRUE)
    {
	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == NUL)
	    return MAYBE;
	if (*p == '}')
	{
	    ++reader->js_used; /* consume the '}' */
	    break;
	}

	ret = json_decode_item(reader, res == NULL ? NULL : &tvkey);
	if (ret != OK)
	    return ret;
	if (res != NULL)
	{
	    key = get_tv_string_buf_chk(&tvkey, buf);
	    if (key == NULL || *key == NUL)
	    {
		clear_tv(&tvkey);
		return FAIL;
	    }
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p != ':')
	{
	    if (res != NULL)
		clear_tv(&tvkey);
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
	++reader->js_used;
	json_skip_white(reader);

	ret = json_decode_item(reader, res == NULL ? NULL : &item);
	if (ret != OK)
	{
	    if (res != NULL)
		clear_tv(&tvkey);
	    return ret;
	}

	if (res != NULL)
	{
	    di = dictitem_alloc(key);
	    clear_tv(&tvkey);
	    if (di == NULL)
	    {
		clear_tv(&item);
		return FAIL;
	    }
	    di->di_tv = item;
	    if (dict_add(res->vval.v_dict, di) == FAIL)
	    {
		dictitem_free(di);
		return FAIL;
	    }
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == ',')
	    ++reader->js_used;
	else if (*p != '}')
	{
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
    }
    return OK;
}

    static int
json_decode_string(js_read_T *reader, typval_T *res)
{
    garray_T    ga;
    int		len;
    char_u	*p;
    int		c;
    long	nr;
    char_u	buf[NUMBUFLEN];

    if (res != NULL)
	ga_init2(&ga, 1, 200);

    p = reader->js_buf + reader->js_used + 1; /* skip over " */
    while (*p != '"')
    {
	if (*p == NUL || p[1] == NUL
#ifdef FEAT_MBYTE
		|| utf_ptr2len(p) < utf_byte2len(*p)
#endif
		)
	{
	    if (reader->js_fill == NULL)
		break;
	    len = (int)(reader->js_end - p);
	    reader->js_used = (int)(p - reader->js_buf);
	    if (!reader->js_fill(reader))
		break; /* didn't get more */
	    p = reader->js_buf + reader->js_used;
	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
	    continue;
	}

	if (*p == '\\')
	{
	    c = -1;
	    switch (p[1])
	    {
		case '\\': c = '\\'; break;
		case '"': c = '"'; break;
		case 'b': c = BS; break;
		case 't': c = TAB; break;
		case 'n': c = NL; break;
		case 'f': c = FF; break;
		case 'r': c = CAR; break;
		case 'u':
		    if (reader->js_fill != NULL
				     && (int)(reader->js_end - p) < NUMBUFLEN)
		    {
			reader->js_used = (int)(p - reader->js_buf);
			if (reader->js_fill(reader))
			{
			    p = reader->js_buf + reader->js_used;
			    reader->js_end = reader->js_buf
						     + STRLEN(reader->js_buf);
			}
		    }
		    vim_str2nr(p + 2, NULL, &len,
				     STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4);
		    p += len + 2;
		    if (res != NULL)
		    {
#ifdef FEAT_MBYTE
			buf[(*mb_char2bytes)((int)nr, buf)] = NUL;
			ga_concat(&ga, buf);
#else
			ga_append(&ga, nr);
#endif
		    }
		    break;
		default:
		    /* not a special char, skip over \ */
		    ++p;
		    continue;
	    }
	    if (c > 0)
	    {
		p += 2;
		if (res != NULL)
		    ga_append(&ga, c);
	    }
	}
	else
	{
	    len = MB_PTR2LEN(p);
	    if (res != NULL)
	    {
		if (ga_grow(&ga, len) == FAIL)
		{
		    ga_clear(&ga);
		    return FAIL;
		}
		mch_memmove((char *)ga.ga_data + ga.ga_len, p, (size_t)len);
		ga.ga_len += len;
	    }
	    p += len;
	}
    }

    reader->js_used = (int)(p - reader->js_buf);
    if (*p == '"')
    {
	++reader->js_used;
	if (res != NULL)
	{
	    res->v_type = VAR_STRING;
	    res->vval.v_string = ga.ga_data;
	}
	return OK;
    }
    if (res != NULL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	ga_clear(&ga);
    }
    return MAYBE;
}

/*
 * Decode one item and put it in "res".  If "res" is NULL only advance.
 * Must already have skipped white space.
 *
 * Return FAIL for a decoding error.
 * Return MAYBE for an incomplete message.
 */
    static int
json_decode_item(js_read_T *reader, typval_T *res)
{
    char_u	*p;
    int		len;

    fill_numbuflen(reader);
    p = reader->js_buf + reader->js_used;
    switch (*p)
    {
	case '[': /* array */
	    return json_decode_array(reader, res);

	case '{': /* object */
	    return json_decode_object(reader, res);

	case '"': /* string */
	    return json_decode_string(reader, res);

	case ',': /* comma: empty item */
	case NUL: /* empty */
	    if (res != NULL)
	    {
		res->v_type = VAR_SPECIAL;
		res->vval.v_number = VVAL_NONE;
	    }
	    return OK;

	default:
	    if (VIM_ISDIGIT(*p) || *p == '-')
	    {
		char_u  *sp = p;

#ifdef FEAT_FLOAT
		if (*sp == '-')
		{
		    ++sp;
		    if (*sp == NUL)
			return MAYBE;
		    if (!VIM_ISDIGIT(*sp))
			return FAIL;
		}
		sp = skipdigits(sp);
		if (*sp == '.' || *sp == 'e' || *sp == 'E')
		{
		    if (res == NULL)
		    {
			float_T f;

			len = string2float(p, &f);
		    }
		    else
		    {
			res->v_type = VAR_FLOAT;
			len = string2float(p, &res->vval.v_float);
		    }
		}
		else
#endif
		{
		    long nr;

		    vim_str2nr(reader->js_buf + reader->js_used,
			    NULL, &len, 0, /* what */
			    &nr, NULL, 0);
		    if (res != NULL)
		    {
			res->v_type = VAR_NUMBER;
			res->vval.v_number = nr;
		    }
		}
		reader->js_used += len;
		return OK;
	    }
	    if (STRNICMP((char *)p, "false", 5) == 0)
	    {
		reader->js_used += 5;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_FALSE;
		}
		return OK;
	    }
	    if (STRNICMP((char *)p, "true", 4) == 0)
	    {
		reader->js_used += 4;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_TRUE;
		}
		return OK;
	    }
	    if (STRNICMP((char *)p, "null", 4) == 0)
	    {
		reader->js_used += 4;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_NULL;
		}
		return OK;
	    }
	    /* check for truncated name */
	    len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
	    if ((len < 5 && STRNICMP((char *)p, "false", len) == 0)
		    || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
			       ||  STRNICMP((char *)p, "null", len) == 0)))
		return MAYBE;
	    break;
    }

    if (res != NUL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
    }
    return FAIL;
}

/*
 * Decode the JSON from "reader" and store the result in "res".
 * Return FAIL if not the whole message was consumed.
 */
    int
json_decode_all(js_read_T *reader, typval_T *res)
{
    int ret;

    /* We get the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, res);
    if (ret != OK)
	return FAIL;
    json_skip_white(reader);
    if (reader->js_buf[reader->js_used] != NUL)
	return FAIL;
    return OK;
}

/*
 * Decode the JSON from "reader" and store the result in "res".
 * Return FAIL if the message has a decoding error or the message is
 * truncated.  Consumes the message anyway.
 */
    int
json_decode(js_read_T *reader, typval_T *res)
{
    int ret;

    /* We get the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, res);
    json_skip_white(reader);

    return ret == OK ? OK : FAIL;
}

/*
 * Decode the JSON from "reader" to find the end of the message.
 * Return FAIL if the message has a decoding error.
 * Return MAYBE if the message is truncated, need to read more.
 * This only works reliable if the message contains an object, array or
 * string.  A number might be trucated without knowing.
 * Does not advance the reader.
 */
    int
json_find_end(js_read_T *reader)
{
    int used_save = reader->js_used;
    int ret;

    /* We get the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, NULL);
    reader->js_used = used_save;
    return ret;
}
#endif
