#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include "json.h"
#include "log.h"

struct json_object *json_create_object(void)
{
	struct json_object *obj = malloc(sizeof(struct json_object));
	if (obj)
		memset(obj, 0, sizeof(struct json_object));
	return obj;
}

struct json_array *json_create_array(void)
{
	struct json_array *array = malloc(sizeof(struct json_array));
	if (array)
		memset(array, 0, sizeof(struct json_array));
	return array;
}

static struct json_pair *json_create_pair(const char *name, struct json_value *value)
{
	struct json_pair *pair = malloc(sizeof(struct json_pair));
	if (pair) {
		pair->name = strdup(name);
		pair->value = value;

		value->parent_type = JSON_PARENT_TYPE_PAIR;
		value->parent_pair = pair;
	}
	return pair;
}

static struct json_value *json_create_value_int(long number)
{
	struct json_value *value = malloc(sizeof(struct json_value));

	if (value) {
		value->type = JSON_TYPE_INTEGER;
		value->integer_number = number;
	}
	return value;
}

static struct json_value *json_create_value_float(float number)
{
	struct json_value *value = malloc(sizeof(struct json_value));

	if (value) {
		value->type = JSON_TYPE_FLOAT;
		value->float_number = number;
	}
	return value;
}

static char *strdup_escape(const char *str)
{
	const char *input = str;
	char *p, *ret;
	int escapes;

	if (!strlen(str))
		return NULL;

	escapes = 0;
	while ((input = strpbrk(input, "\\\"")) != NULL) {
		escapes++;
		input++;
	}

	p = ret = malloc(strlen(str) + escapes + 1);
	while (*str) {
		if (*str == '\\' || *str == '\"')
			*p++ = '\\';
		*p++ = *str++;
	}
	*p = '\0';

	return ret;
}

/*
 * Valid JSON strings must escape '"' and '/' with a preceeding '/'
 */
static struct json_value *json_create_value_string(const char *str)
{
	struct json_value *value = malloc(sizeof(struct json_value));

	if (value) {
		value->type = JSON_TYPE_STRING;
		value->string = strdup_escape(str);
		if (!value->string) {
			free(value);
			value = NULL;
		}
	}
	return value;
}

static struct json_value *json_create_value_object(struct json_object *obj)
{
	struct json_value *value = malloc(sizeof(struct json_value));

	if (value) {
		value->type = JSON_TYPE_OBJECT;
		value->object = obj;
		obj->parent = value;
	}
	return value;
}

static struct json_value *json_create_value_array(struct json_array *array)
{
	struct json_value *value = malloc(sizeof(struct json_value));

	if (value) {
		value->type = JSON_TYPE_ARRAY;
		value->array = array;
		array->parent = value;
	}
	return value;
}

static void json_free_pair(struct json_pair *pair);
static void json_free_value(struct json_value *value);

void json_free_object(struct json_object *obj)
{
	int i;

	for (i = 0; i < obj->pair_cnt; i++)
		json_free_pair(obj->pairs[i]);
	free(obj->pairs);
	free(obj);
}

static void json_free_array(struct json_array *array)
{
	int i;

	for (i = 0; i < array->value_cnt; i++)
		json_free_value(array->values[i]);
	free(array->values);
	free(array);
}

static void json_free_pair(struct json_pair *pair)
{
	json_free_value(pair->value);
	free(pair->name);
	free(pair);
}

static void json_free_value(struct json_value *value)
{
	switch (value->type) {
	case JSON_TYPE_STRING:
		free(value->string);
		break;
	case JSON_TYPE_OBJECT:
		json_free_object(value->object);
		break;
	case JSON_TYPE_ARRAY:
		json_free_array(value->array);
		break;
	}
	free(value);
}

static int json_array_add_value(struct json_array *array, struct json_value *value)
{
	struct json_value **values = realloc(array->values,
		sizeof(struct json_value *) * (array->value_cnt + 1));

	if (!values)
		return ENOMEM;
	values[array->value_cnt] = value;
	array->value_cnt++;
	array->values = values;

	value->parent_type = JSON_PARENT_TYPE_ARRAY;
	value->parent_array = array;
	return 0;
}

static int json_object_add_pair(struct json_object *obj, struct json_pair *pair)
{
	struct json_pair **pairs = realloc(obj->pairs,
		sizeof(struct json_pair *) * (obj->pair_cnt + 1));
	if (!pairs)
		return ENOMEM;
	pairs[obj->pair_cnt] = pair;
	obj->pair_cnt++;
	obj->pairs = pairs;

	pair->parent = obj;
	return 0;
}

int json_object_add_value_type(struct json_object *obj, const char *name, int type, ...)
{
	struct json_value *value;
	struct json_pair *pair;
	va_list args;
	int ret;

	va_start(args, type);
	if (type == JSON_TYPE_STRING)
		value = json_create_value_string(va_arg(args, char *));
	else if (type == JSON_TYPE_INTEGER)
		value = json_create_value_int(va_arg(args, long));
	else if (type == JSON_TYPE_FLOAT)
		value = json_create_value_float(va_arg(args, double));
	else if (type == JSON_TYPE_OBJECT)
		value = json_create_value_object(va_arg(args, struct json_object *));
	else
		value = json_create_value_array(va_arg(args, struct json_array *));
	va_end(args);

	if (!value)
		return ENOMEM;

	pair = json_create_pair(name, value);
	if (!pair) {
		json_free_value(value);
		return ENOMEM;
	}
	ret = json_object_add_pair(obj, pair);
	if (ret) {
		json_free_pair(pair);
		return ENOMEM;
	}
	return 0;
}

static void json_print_array(struct json_array *array);
int json_array_add_value_type(struct json_array *array, int type, ...)
{
	struct json_value *value;
	va_list args;
	int ret;

	va_start(args, type);
	if (type == JSON_TYPE_STRING)
		value = json_create_value_string(va_arg(args, char *));
	else if (type == JSON_TYPE_INTEGER)
		value = json_create_value_int(va_arg(args, long));
	else if (type == JSON_TYPE_FLOAT)
		value = json_create_value_float(va_arg(args, double));
	else if (type == JSON_TYPE_OBJECT)
		value = json_create_value_object(va_arg(args, struct json_object *));
	else
		value = json_create_value_array(va_arg(args, struct json_array *));
	va_end(args);

	if (!value)
		return ENOMEM;

	ret = json_array_add_value(array, value);
	if (ret) {
		json_free_value(value);
		return ENOMEM;
	}
	return 0;
}

static int json_value_level(struct json_value *value);
static int json_pair_level(struct json_pair *pair);
static int json_array_level(struct json_array *array);
static int json_object_level(struct json_object *object)
{
	if (object->parent == NULL)
		return 0;
	return json_value_level(object->parent);
}

static int json_pair_level(struct json_pair *pair)
{
	return json_object_level(pair->parent) + 1;
}

static int json_array_level(struct json_array *array)
{
	return json_value_level(array->parent);
}

static int json_value_level(struct json_value *value)
{
	if (value->parent_type == JSON_PARENT_TYPE_PAIR)
		return json_pair_level(value->parent_pair);
	else
		return json_array_level(value->parent_array) + 1;
}

static void json_print_level(int level)
{
	while (level-- > 0)
		log_info("  ");
}

static void json_print_pair(struct json_pair *pair);
static void json_print_array(struct json_array *array);
static void json_print_value(struct json_value *value);
void json_print_object(struct json_object *obj)
{
	int i;

	log_info("{\n");
	for (i = 0; i < obj->pair_cnt; i++) {
		if (i > 0)
			log_info(",\n");
		json_print_pair(obj->pairs[i]);
	}
	log_info("\n");
	json_print_level(json_object_level(obj));
	log_info("}");
}

static void json_print_pair(struct json_pair *pair)
{
	json_print_level(json_pair_level(pair));
	log_info("\"%s\" : ", pair->name);
	json_print_value(pair->value);
}

static void json_print_array(struct json_array *array)
{
	int i;

	log_info("[\n");
	for (i = 0; i < array->value_cnt; i++) {
		if (i > 0)
			log_info(",\n");
		json_print_level(json_value_level(array->values[i]));
		json_print_value(array->values[i]);
	}
	log_info("\n");
	json_print_level(json_array_level(array));
	log_info("]");
}

static void json_print_value(struct json_value *value)
{
	switch (value->type) {
	case JSON_TYPE_STRING:
		log_info("\"%s\"", value->string);
		break;
	case JSON_TYPE_INTEGER:
		log_info("%ld", value->integer_number);
		break;
	case JSON_TYPE_FLOAT:
		log_info("%.2f", value->float_number);
		break;
	case JSON_TYPE_OBJECT:
		json_print_object(value->object);
		break;
	case JSON_TYPE_ARRAY:
		json_print_array(value->array);
		break;
	}
}
