#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)
{
	return calloc(1, sizeof(struct json_object));
}

struct json_array *json_create_array(void)
{
	return calloc(1, sizeof(struct json_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 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 preceding '/'
 */
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 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 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("%lld", 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;
	}
}
