/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */
/*
 * Simple streaming JSON writer
 *
 * This takes care of the annoying bits of JSON syntax like the commas
 * after elements
 *
 * Authors:	Stephen Hemminger <stephen@networkplumber.org>
 */

#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>
#include <assert.h>
#include <malloc.h>
#include <inttypes.h>
#include <stdint.h>

#include "json_writer.h"

struct json_writer {
	FILE		*out;	/* output file */
	unsigned	depth;  /* nesting */
	bool		pretty; /* optional whitepace */
	char		sep;	/* either nul or comma */
};

/* indentation for pretty print */
static void jsonw_indent(json_writer_t *self)
{
	unsigned i;
	for (i = 0; i < self->depth; ++i)
		fputs("    ", self->out);
}

/* end current line and indent if pretty printing */
static void jsonw_eol(json_writer_t *self)
{
	if (!self->pretty)
		return;

	putc('\n', self->out);
	jsonw_indent(self);
}

/* If current object is not empty print a comma */
static void jsonw_eor(json_writer_t *self)
{
	if (self->sep != '\0')
		putc(self->sep, self->out);
	self->sep = ',';
}


/* Output JSON encoded string */
/* Handles C escapes, does not do Unicode */
static void jsonw_puts(json_writer_t *self, const char *str)
{
	putc('"', self->out);
	for (; *str; ++str)
		switch (*str) {
		case '\t':
			fputs("\\t", self->out);
			break;
		case '\n':
			fputs("\\n", self->out);
			break;
		case '\r':
			fputs("\\r", self->out);
			break;
		case '\f':
			fputs("\\f", self->out);
			break;
		case '\b':
			fputs("\\b", self->out);
			break;
		case '\\':
			fputs("\\\\", self->out);
			break;
		case '"':
			fputs("\\\"", self->out);
			break;
		case '\'':
			fputs("\\\'", self->out);
			break;
		default:
			putc(*str, self->out);
		}
	putc('"', self->out);
}

/* Create a new JSON stream */
json_writer_t *jsonw_new(FILE *f)
{
	json_writer_t *self = malloc(sizeof(*self));
	if (self) {
		self->out = f;
		self->depth = 0;
		self->pretty = false;
		self->sep = '\0';
	}
	return self;
}

/* End output to JSON stream */
void jsonw_destroy(json_writer_t **self_p)
{
	json_writer_t *self = *self_p;

	assert(self->depth == 0);
	fputs("\n", self->out);
	fflush(self->out);
	free(self);
	*self_p = NULL;
}

void jsonw_pretty(json_writer_t *self, bool on)
{
	self->pretty = on;
}

/* Basic blocks */
static void jsonw_begin(json_writer_t *self, int c)
{
	jsonw_eor(self);
	putc(c, self->out);
	++self->depth;
	self->sep = '\0';
}

static void jsonw_end(json_writer_t *self, int c)
{
	assert(self->depth > 0);

	--self->depth;
	if (self->sep != '\0')
		jsonw_eol(self);
	putc(c, self->out);
	self->sep = ',';
}


/* Add a JSON property name */
void jsonw_name(json_writer_t *self, const char *name)
{
	jsonw_eor(self);
	jsonw_eol(self);
	self->sep = '\0';
	jsonw_puts(self, name);
	putc(':', self->out);
	if (self->pretty)
		putc(' ', self->out);
}

__attribute__((format(printf, 2, 3)))
void jsonw_printf(json_writer_t *self, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	jsonw_eor(self);
	vfprintf(self->out, fmt, ap);
	va_end(ap);
}

/* Collections */
void jsonw_start_object(json_writer_t *self)
{
	jsonw_begin(self, '{');
}

void jsonw_end_object(json_writer_t *self)
{
	jsonw_end(self, '}');
}

void jsonw_start_array(json_writer_t *self)
{
	jsonw_begin(self, '[');
	if (self->pretty)
		putc(' ', self->out);
}

void jsonw_end_array(json_writer_t *self)
{
	if (self->pretty && self->sep)
		putc(' ', self->out);
	self->sep = '\0';
	jsonw_end(self, ']');
}

/* JSON value types */
void jsonw_string(json_writer_t *self, const char *value)
{
	jsonw_eor(self);
	jsonw_puts(self, value);
}

void jsonw_bool(json_writer_t *self, bool val)
{
	jsonw_printf(self, "%s", val ? "true" : "false");
}

void jsonw_null(json_writer_t *self)
{
	jsonw_printf(self, "null");
}

void jsonw_float(json_writer_t *self, double num)
{
	jsonw_printf(self, "%g", num);
}

void jsonw_hhu(json_writer_t *self, unsigned char num)
{
	jsonw_printf(self, "%hhu", num);
}

void jsonw_hu(json_writer_t *self, unsigned short num)
{
	jsonw_printf(self, "%hu", num);
}

void jsonw_uint(json_writer_t *self, unsigned int num)
{
	jsonw_printf(self, "%u", num);
}

void jsonw_u64(json_writer_t *self, uint64_t num)
{
	jsonw_printf(self, "%"PRIu64, num);
}

void jsonw_xint(json_writer_t *self, uint64_t num)
{
	jsonw_printf(self, "%"PRIx64, num);
}

void jsonw_luint(json_writer_t *self, unsigned long num)
{
	jsonw_printf(self, "%lu", num);
}

void jsonw_lluint(json_writer_t *self, unsigned long long num)
{
	jsonw_printf(self, "%llu", num);
}

void jsonw_int(json_writer_t *self, int num)
{
	jsonw_printf(self, "%d", num);
}

void jsonw_s64(json_writer_t *self, int64_t num)
{
	jsonw_printf(self, "%"PRId64, num);
}

/* Basic name/value objects */
void jsonw_string_field(json_writer_t *self, const char *prop, const char *val)
{
	jsonw_name(self, prop);
	jsonw_string(self, val);
}

void jsonw_bool_field(json_writer_t *self, const char *prop, bool val)
{
	jsonw_name(self, prop);
	jsonw_bool(self, val);
}

void jsonw_float_field(json_writer_t *self, const char *prop, double val)
{
	jsonw_name(self, prop);
	jsonw_float(self, val);
}

void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num)
{
	jsonw_name(self, prop);
	jsonw_uint(self, num);
}

void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num)
{
	jsonw_name(self, prop);
	jsonw_u64(self, num);
}

void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num)
{
	jsonw_name(self, prop);
	jsonw_xint(self, num);
}

void jsonw_hhu_field(json_writer_t *self, const char *prop, unsigned char num)
{
	jsonw_name(self, prop);
	jsonw_hhu(self, num);
}

void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num)
{
	jsonw_name(self, prop);
	jsonw_hu(self, num);
}

void jsonw_luint_field(json_writer_t *self,
			const char *prop,
			unsigned long num)
{
	jsonw_name(self, prop);
	jsonw_luint(self, num);
}

void jsonw_lluint_field(json_writer_t *self,
			const char *prop,
			unsigned long long num)
{
	jsonw_name(self, prop);
	jsonw_lluint(self, num);
}

void jsonw_int_field(json_writer_t *self, const char *prop, int num)
{
	jsonw_name(self, prop);
	jsonw_int(self, num);
}

void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num)
{
	jsonw_name(self, prop);
	jsonw_s64(self, num);
}

void jsonw_null_field(json_writer_t *self, const char *prop)
{
	jsonw_name(self, prop);
	jsonw_null(self);
}

#ifdef TEST
int main(int argc, char **argv)
{
	json_writer_t *wr = jsonw_new(stdout);

	jsonw_start_object(wr);
	jsonw_pretty(wr, true);
	jsonw_name(wr, "Vyatta");
	jsonw_start_object(wr);
	jsonw_string_field(wr, "url", "http://vyatta.com");
	jsonw_uint_field(wr, "downloads", 2000000ul);
	jsonw_float_field(wr, "stock", 8.16);

	jsonw_name(wr, "ARGV");
	jsonw_start_array(wr);
	while (--argc)
		jsonw_string(wr, *++argv);
	jsonw_end_array(wr);

	jsonw_name(wr, "empty");
	jsonw_start_array(wr);
	jsonw_end_array(wr);

	jsonw_name(wr, "NIL");
	jsonw_start_object(wr);
	jsonw_end_object(wr);

	jsonw_null_field(wr, "my_null");

	jsonw_name(wr, "special chars");
	jsonw_start_array(wr);
	jsonw_string_field(wr, "slash", "/");
	jsonw_string_field(wr, "newline", "\n");
	jsonw_string_field(wr, "tab", "\t");
	jsonw_string_field(wr, "ff", "\f");
	jsonw_string_field(wr, "quote", "\"");
	jsonw_string_field(wr, "tick", "\'");
	jsonw_string_field(wr, "backslash", "\\");
	jsonw_end_array(wr);

	jsonw_end_object(wr);

	jsonw_end_object(wr);
	jsonw_destroy(&wr);
	return 0;
}

#endif
