#include <string.h>
#include <stdio.h>

#include "json_utils.h"
#include "escape_unescape.h"
#define PRINT_TIME_TAG
#define DBG_TAG "json_utils"
#define DBG_LVL DBG_INFO
#include "debug_print.h"

int get_size_from_json_arry_by_key(struct json_object *root, char *key, int *size)
{
	int ret = -1;
	struct json_object *node = NULL;
	size_t arry_size = 0;

	node = json_object_object_get(root, key);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	arry_size = json_object_array_length(node);
	if(size != NULL){
		*size = arry_size;
	}
	ret = 0;
error:
	return ret;
}

int get_int_from_json_by_key(struct json_object *root, char *key, int *value)
{
	struct json_object *node;
	int ret = -1;

	if ((key == NULL) || (value == NULL))
	{
		LOG_I("parameter cannot be a null pointer\n");
		goto error;
	}
	node = json_object_object_get(root, key);
	if (node == NULL)
	{
		LOG_I("json_object_object_get error\n");
		goto error;
	}
	*value = json_object_get_int(node);
	ret = 0;
error:
	return ret;
}

int get_string_from_json_by_key_unescape(struct json_object *root, char *key, char *str, int str_len)
{
	struct json_object *node;
	const char *str_ptr = NULL;
	char str_cache[3072] = "";
	int ret = -1;

	node = json_object_object_get(root, key);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	str_ptr = json_object_to_json_string(node);
	if ((strncmp(str_ptr, "null", strlen("null")) != 0) && (str != NULL))
	{
		memset(str, 0, str_len);
		//LOG_D("eacape debug:starting ...\n");
		//LOG_D("str_ptr[%s]\n", str_ptr);
		unescape(str_ptr, str_cache, sizeof(str_cache));
		//LOG_D("str_cache[%s]\n", str_cache);
		//LOG_D("eacape debug:finished\n");
		if ((strlen(str_cache) - 2) <= str_len)
		{
			memcpy(str, str_cache + 1, strlen(str_cache) - 2);
			ret = 0;
		}
	}
error:
	return ret;
}

int get_string_from_json_by_key(struct json_object *root, char *key, char *str, int str_len)
{
	struct json_object *node;
	const char *str_ptr = NULL;
	int ret = -1;

	node = json_object_object_get(root, key);
	if (node == NULL)
	{
		goto error;
	}
	str_ptr = json_object_to_json_string(node);
	if ((strncmp(str_ptr, "null", strlen("null")) != 0) && (str != NULL))
	{
		memset(str, 0, str_len);
		if ((strlen(str_ptr) - 2) <= str_len)
		{
			memcpy(str, str_ptr + 1, strlen(str_ptr) - 2);
			ret = 0;
		}
	}
error:
	return ret;
}

int get_string_from_json_arry_by_key_unescape(struct json_object *root, char *key, char *str, int str_len, int index)
{
	int ret = -1;
	struct json_object *arry;
	struct json_object *node;
	const char *str_ptr = NULL;
	char str_cache[3072] = "";
	int size = 0;

	ret = get_size_from_json_arry_by_key(root, key, &size);
	if((index > (size - 1))||(ret != 0)){
		ret = -1;
		goto error;
	}
	arry = json_object_object_get(root, key);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	node = json_object_array_get_idx(arry, index);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	str_ptr = json_object_to_json_string(node);
	if ((strncmp(str_ptr, "null", strlen("null")) != 0) && (str != NULL))
	{
		memset(str, 0, str_len);
		//LOG_D("eacape debug:starting ...\n");
		//LOG_D("str_ptr[%s]\n", str_ptr);
		unescape(str_ptr, str_cache, sizeof(str_cache));
		//LOG_D("str_cache[%s]\n", str_cache);
		//LOG_D("eacape debug:finished\n");
		if ((strlen(str_cache) - 2) <= str_len)
		{
			memcpy(str, str_cache + 1, strlen(str_cache) - 2);
			ret = 0;
		}
	}
error:
	return ret;
}

int get_string_from_json_arry_by_key(struct json_object *root, char *key, char *str, int str_len, int index)
{
	int ret = -1;
	struct json_object *arry;
	struct json_object *node;
	const char *str_ptr = NULL;
	int size = 0;

	ret = get_size_from_json_arry_by_key(root, key, &size);
	if((index > (size - 1))||(ret != 0)){
		ret = -1;
		goto error;
	}
	arry = json_object_object_get(root, key);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	node = json_object_array_get_idx(arry, index);
	if (node == NULL)
	{
		//LOG_I("NULL pointer\n");
		goto error;
	}
	str_ptr = json_object_to_json_string(node);
	if ((strncmp(str_ptr, "null", strlen("null")) != 0) && (str != NULL))
	{
		memset(str, 0, str_len);
		if ((strlen(str_ptr) - 2) <= str_len)
		{
			memcpy(str, str_ptr + 1, strlen(str_ptr) - 2);
			ret = 0;
		}
	}
error:
	return ret;
}

int get_size_from_json_string_arry_by_key(char *json_buffer, char *key, int *size)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_size_from_json_arry_by_key(parse_obj, key, size);
error:
	json_object_put(parse_obj);
	return ret;
}

int get_int_from_json_string_by_key(char *json_buffer, char *key, int *value)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_int_from_json_by_key(parse_obj, key, value);
error:
	json_object_put(parse_obj);
	return ret;
}

int get_string_from_json_string_arry_by_key_unescape(char *json_buffer, char *key, char *str, int str_len, int index)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_string_from_json_arry_by_key_unescape(parse_obj, key, str, str_len, index);
error:
	json_object_put(parse_obj);
	return ret;
}

int get_string_from_json_string_arry_by_key(char *json_buffer, char *key, char *str, int str_len, int index)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_string_from_json_arry_by_key(parse_obj, key, str, str_len, index);
error:
	json_object_put(parse_obj);
	return ret;
}

int get_string_from_json_string_by_key_unescape(char *json_buffer, char *key, char *str, int str_len)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_string_from_json_by_key_unescape(parse_obj, key, str, str_len);
error:
	json_object_put(parse_obj);
	return ret;
}

int get_string_from_json_string_by_key(char *json_buffer, char *key, char *str, int str_len)
{
	int ret = -1;
	struct json_object* parse_obj = NULL;

	if(json_buffer == NULL)
	{
		LOG_I("param: NULL\n");
		return -1;
	}
	parse_obj = json_tokener_parse(json_buffer);
	if (parse_obj == NULL)
	{
		LOG_I("json_tokener_parse\n");
		ret = -2;
		goto error;
	}
	ret = get_string_from_json_by_key(parse_obj, key, str, str_len);
error:
	json_object_put(parse_obj);
	return ret;
}
