/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2018  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

#include <ell/ell.h>

#include "mesh/mesh-defs.h"
#include "mesh/util.h"

#include "mesh/mesh-db.h"

#define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))

static bool get_int(json_object *jobj, const char *keyword, int *value)
{
	json_object *jvalue;

	if (!json_object_object_get_ex(jobj, keyword, &jvalue))
		return false;

	*value = json_object_get_int(jvalue);
	if (errno == EINVAL)
		return false;

	return true;
}

static bool add_key(json_object *jobject, const char *desc,
					const uint8_t key[16])
{
	json_object *jstring;
	char hexstr[33];

	hex2str((uint8_t *) key, 16, hexstr, 33);
	jstring = json_object_new_string(hexstr);
	if (!jstring)
		return false;

	json_object_object_add(jobject, desc, jstring);
	return true;
}

static json_object *get_element_model(json_object *jnode, int ele_idx,
						uint32_t mod_id, bool vendor)
{
	json_object *jelements, *jelement, *jmodels;
	int i, num_mods;
	size_t len;
	char buf[9];

	if (!vendor)
		snprintf(buf, 5, "%4.4x", (uint16_t)mod_id);
	else
		snprintf(buf, 9, "%8.8x", mod_id);

	json_object_object_get_ex(jnode, "elements", &jelements);
	if (!jelements)
		return NULL;

	jelement = json_object_array_get_idx(jelements, ele_idx);
	if (!jelement)
		return NULL;

	json_object_object_get_ex(jelement, "models", &jmodels);
	if (!jmodels)
		return NULL;

	num_mods = json_object_array_length(jmodels);
	if (!num_mods)
		return NULL;

	if (!vendor) {
		snprintf(buf, 5, "%4.4x", mod_id);
		len = 4;
	} else {
		snprintf(buf, 9, "%8.8x", mod_id);
		len = 8;
	}

	for (i = 0; i < num_mods; ++i) {
		json_object *jmodel, *jvalue;
		char *str;

		jmodel = json_object_array_get_idx(jmodels, i);
		json_object_object_get_ex(jmodel, "modelId", &jvalue);
		if (!jvalue)
			return NULL;

		str = (char *)json_object_get_string(jvalue);
		if (!str)
			return NULL;

		if (!strncmp(str, buf, len))
			return jmodel;
	}

	return NULL;
}

static bool jarray_has_string(json_object *jarray, char *str, size_t len)
{
	int i, sz = json_object_array_length(jarray);

	for (i = 0; i < sz; ++i) {
		json_object *jentry;
		char *str_entry;

		jentry = json_object_array_get_idx(jarray, i);
		str_entry = (char *)json_object_get_string(jentry);
		if (!str_entry)
			continue;

		if (!strncmp(str, str_entry, len))
			return true;
	}

	return false;
}

static json_object *jarray_string_del(json_object *jarray, char *str,
								size_t len)
{
	int i, sz = json_object_array_length(jarray);
	json_object *jarray_new;

	jarray_new = json_object_new_array();
	if (!jarray_new)
		return NULL;

	for (i = 0; i < sz; ++i) {
		json_object *jentry;
		char *str_entry;

		jentry = json_object_array_get_idx(jarray, i);
		str_entry = (char *)json_object_get_string(jentry);
		if (str_entry && !strncmp(str, str_entry, len))
			continue;

		json_object_array_add(jarray_new, jentry);
	}

	return jarray_new;
}

static json_object *get_key_object(json_object *jarray, uint16_t idx)
{
	int i, sz = json_object_array_length(jarray);

	for (i = 0; i < sz; ++i) {
		json_object *jentry, *jvalue;
		uint32_t jidx;

		jentry = json_object_array_get_idx(jarray, i);
		if (!json_object_object_get_ex(jentry, "index", &jvalue))
			return NULL;

		jidx = json_object_get_int(jvalue);

		if (jidx == idx)
			return jentry;
	}

	return NULL;
}

static json_object *jarray_key_del(json_object *jarray, int16_t idx)
{
	json_object *jarray_new;
	int i, sz = json_object_array_length(jarray);
	char idx_str[5];

	snprintf(idx_str, 5, "%4.4x", idx);

	jarray_new = json_object_new_array();
	if (!jarray_new)
		return NULL;

	for (i = 0; i < sz; ++i) {
		json_object *jentry, *jvalue;
		char *str;

		jentry = json_object_array_get_idx(jarray, i);

		if (json_object_object_get_ex(jentry, "index", &jvalue)) {
			str = (char *)json_object_get_string(jvalue);
			if (str && !strncmp(str, idx_str, 4))
				continue;
		}

		json_object_array_add(jarray_new, jentry);
	}

	return jarray_new;
}

bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
{
	int tmp;

	/* IV index */
	if (!get_int(jobj, "IVindex", &tmp))
		return false;

	*idx = (uint32_t) tmp;

	if (!get_int(jobj, "IVupdate", &tmp))
		return false;

	*update = tmp ? true : false;

	return true;
}

bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
{
	json_object *jvalue;
	char *str;

	if (!key_buf)
		return false;

	if (!json_object_object_get_ex(jobj, "deviceKey", &jvalue) ||
								!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (!str2hex(str, strlen(str), key_buf, 16))
		return false;

	return true;
}

bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
							void *user_data)
{
	json_object *jarray;
	int len;
	int i;

	if (!cb)
		return true;

	json_object_object_get_ex(jobj, "appKeys", &jarray);
	if (!jarray || (json_object_get_type(jarray) != json_type_array))
		return false;

	len = json_object_array_length(jarray);

	for (i = 0; i < len; ++i) {
		json_object *jtemp, *jvalue;
		int app_idx, net_idx;
		bool key_refresh = false;
		char *str;
		uint8_t key[16];
		uint8_t new_key[16];

		jtemp = json_object_array_get_idx(jarray, i);

		if (!get_int(jtemp, "index", &app_idx))
			return false;

		if (!CHECK_KEY_IDX_RANGE(app_idx))
			return false;

		if (!get_int(jtemp, "boundNetKey", &net_idx))
			return false;

		if (!CHECK_KEY_IDX_RANGE(net_idx))
			return false;

		json_object_object_get_ex(jtemp, "oldKey", &jvalue);
		if (jvalue) {
			str = (char *)json_object_get_string(jvalue);
			if (!str2hex(str, strlen(str), key, 16))
				return false;
			key_refresh = true;
		}

		json_object_object_get_ex(jtemp, "key", &jvalue);
		if (!jvalue)
			return false;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
			return false;

		if (!cb((uint16_t)net_idx, (uint16_t) app_idx, key,
				key_refresh ? new_key : NULL, user_data))
			return false;
	}

	return true;
}

bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
								void *user_data)
{
	json_object *jarray;
	int len;
	int i;

	if (!cb)
		return true;

	json_object_object_get_ex(jobj, "netKeys", &jarray);
	if (!jarray || (json_object_get_type(jarray) != json_type_array))
		return false;

	len = json_object_array_length(jarray);

	for (i = 0; i < len; ++i) {
		json_object *jtemp, *jvalue;
		int idx;
		char *str;
		bool key_refresh = false;
		int phase;
		uint8_t key[16];
		uint8_t new_key[16];

		jtemp = json_object_array_get_idx(jarray, i);

		if (!get_int(jtemp, "index", &idx))
			return false;

		if (!CHECK_KEY_IDX_RANGE(idx))
			return false;

		json_object_object_get_ex(jtemp, "oldKey", &jvalue);
		if (jvalue) {
			str = (char *)json_object_get_string(jvalue);
			if (!str2hex(str, strlen(str), key, 16))
				return false;
			key_refresh = true;
		}

		json_object_object_get_ex(jtemp, "key", &jvalue);
		if (!jvalue)
			return false;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
			return false;

		json_object_object_get_ex(jtemp, "keyRefresh", &jvalue);
		if (!jvalue)
			phase = KEY_REFRESH_PHASE_NONE;
		else
			phase = json_object_get_int(jvalue);


		if (!cb((uint16_t)idx, key, key_refresh ? new_key : NULL, phase,
								user_data))
			return false;
	}

	return true;
}

bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
					const uint8_t key[16], int phase)
{
	json_object *jarray, *jentry = NULL, *jstring;
	char buf[5];

	json_object_object_get_ex(jobj, "netKeys", &jarray);
	if (!jarray && (phase != KEY_REFRESH_PHASE_NONE))
		return false;

	if (jarray)
		jentry = get_key_object(jarray, idx);

	/*
	 * The key entry should exist if the key is updated
	 * (i.e., Key Refresh is underway)
	 */
	if (!jentry && (phase != KEY_REFRESH_PHASE_NONE))
		return false;

	if (jentry) {
		uint8_t buf[16];
		json_object *jvalue;
		char *str;

		json_object_object_get_ex(jentry, "key", &jvalue);
		if (!jvalue)
			return false;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), buf, sizeof(buf)))
			return false;

		/* If the same key, return success */
		if (memcmp(key, buf, 16) == 0)
			return true;

		return false;
	}

	if (phase == KEY_REFRESH_PHASE_NONE) {
		jentry = json_object_new_object();
		if (!jentry)
			goto fail;

		snprintf(buf, 5, "%4.4x", idx);
		jstring = json_object_new_string(buf);
		if (!jstring)
			goto fail;

		json_object_object_add(jentry, "index", jstring);

		snprintf(buf, 5, "%4.4x", idx);
		jstring = json_object_new_string(buf);
		if (!jstring)
			goto fail;

		if (!add_key(jentry, "key", key))
			goto fail;

		if (!jarray) {
			jarray = json_object_new_array();
			if (!jarray)
				goto fail;
			json_object_object_add(jobj, "netKeys", jarray);
		}

		json_object_array_add(jarray, jentry);

	} else {

		if (!json_object_object_get_ex(jentry, "key", &jstring))
			return false;

		json_object_object_add(jentry, "oldKey", jstring);
		json_object_object_del(jentry, "key");

		if (!add_key(jentry, "key", key))
			return false;
	}


	json_object_object_add(jentry, "keyRefresh",
					json_object_new_int(phase));

	return true;
fail:

	if (jentry)
		json_object_put(jentry);

	return false;
}

bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
{
	json_object *jarray, *jarray_new;

	json_object_object_get_ex(jobj, "netKeys", &jarray);
	if (!jarray)
		return true;

	/* Check if matching entry exists */
	if (!get_key_object(jarray, idx))
		return true;

	if (json_object_array_length(jarray) == 1) {
		json_object_object_del(jobj, "netKeys");
		return true;
	}

	/*
	 * There is no easy way to delete a value from json array.
	 * Create a new copy without specified element and
	 * then remove old array.
	 */
	jarray_new = jarray_key_del(jarray, idx);
	if (!jarray_new)
		return false;

	json_object_object_del(jobj, "netKeys");
	json_object_object_add(jobj, "netKeys", jarray_new);

	return true;
}

bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
{
	return add_key(jnode, "deviceKey", key);
}

bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
			 const uint8_t key[16], bool update)
{
	json_object *jarray, *jentry = NULL, *jstring = NULL;
	char buf[5];

	json_object_object_get_ex(jobj, "appKeys", &jarray);
	if (!jarray && update)
		return false;

	if (jarray)
		jentry = get_key_object(jarray, app_idx);

	/* The key entry should exist if the key is updated */
	if (!jentry  && update)
		return false;

	if (jentry) {
		uint8_t buf[16];
		json_object *jvalue;
		char *str;

		json_object_object_get_ex(jentry, "key", &jvalue);
		if (!jvalue)
			return false;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), buf, sizeof(buf)))
			return false;

		/* If the same key, return success */
		if (memcmp(key, buf, 16) == 0)
			return true;

		return false;
	}

	if (!update) {
		jentry = json_object_new_object();
		if (!jentry)
			goto fail;

		snprintf(buf, 5, "%4.4x", app_idx);
		jstring = json_object_new_string(buf);
		if (!jstring)
			goto fail;

		json_object_object_add(jentry, "index", jstring);

		snprintf(buf, 5, "%4.4x", net_idx);
		jstring = json_object_new_string(buf);
		if (!jstring)
			goto fail;

		json_object_object_add(jentry, "boundNetKey", jstring);

		if (!add_key(jentry, "key", key))
			goto fail;

		if (!jarray) {
			jarray = json_object_new_array();
			if (!jarray)
				goto fail;
			json_object_object_add(jobj, "appKeys", jarray);
		}

		json_object_array_add(jarray, jentry);

	} else {

		if (!json_object_object_get_ex(jentry, "key", &jstring))
			return false;

		json_object_object_add(jentry, "oldKey", jstring);
		json_object_object_del(jentry, "key");

		if (!add_key(jentry, "key", key))
			return false;
	}

	return true;
fail:

	if (jentry)
		json_object_put(jentry);

	return false;
}

bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
{
	json_object *jarray, *jarray_new;

	json_object_object_get_ex(jobj, "appKeys", &jarray);
	if (!jarray)
		return true;

	/* Check if matching entry exists */
	if (!get_key_object(jarray, idx))
		return true;

	if (json_object_array_length(jarray) == 1) {
		json_object_object_del(jobj, "appKeys");
		return true;
	}

	/*
	 * There is no easy way to delete a value from json array.
	 * Create a new copy without specified element and
	 * then remove old array.
	 */
	jarray_new = jarray_key_del(jarray, idx);
	if (!jarray_new)
		return false;

	json_object_object_del(jobj, "appKeys");
	json_object_object_add(jobj, "appKeys", jarray_new);

	return true;
}

bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
				uint32_t mod_id, uint16_t app_idx)
{
	json_object *jmodel, *jstring, *jarray;
	char buf[5];

	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
	if (!jmodel)
		return false;

	json_object_object_get_ex(jmodel, "bind", &jarray);

	snprintf(buf, 5, "%4.4x", app_idx);

	if (jarray && jarray_has_string(jarray, buf, 4))
		return true;

	jstring = json_object_new_string(buf);
	if (!jstring)
		return false;

	if (!jarray) {
		jarray = json_object_new_array();
		if (!jarray) {
			json_object_put(jstring);
			return false;
		}
		json_object_object_add(jmodel, "bind", jarray);
	}

	json_object_array_add(jarray, jstring);

	return true;
}

bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
				uint32_t mod_id, uint16_t app_idx)
{
	json_object *jmodel, *jarray, *jarray_new;
	char buf[5];

	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
	if (!jmodel)
		return false;

	json_object_object_get_ex(jmodel, "bind", &jarray);

	snprintf(buf, 5, "%4.4x", app_idx);

	if (!jarray || !jarray_has_string(jarray, buf, 4))
		return true;

	if (json_object_array_length(jarray) == 1) {
		json_object_object_del(jmodel, "bind");
		return true;
	}

	/*
	 * There is no easy way to delete a value from json array.
	 * Create a new copy without specified element and
	 * then remove old array.
	 */
	jarray_new = jarray_string_del(jarray, buf, 4);
	if (!jarray_new)
		return false;

	json_object_object_del(jmodel, "bind");
	json_object_object_add(jmodel, "bind", jarray_new);

	return true;
}

static void free_model(void *data)
{
	struct mesh_db_model *mod = data;

	l_free(mod->bindings);
	l_free(mod->subs);
	l_free(mod->pub);
	l_free(mod);
}

static void free_element(void *data)
{
	struct mesh_db_element *ele = data;

	l_queue_destroy(ele->models, free_model);
	l_free(ele);
}

static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
{
	int cnt;
	int i;

	cnt = json_object_array_length(jbindings);
	if (cnt > 0xffff)
		return false;

	mod->num_subs = cnt;

	/* Allow empty bindings list */
	if (!cnt)
		return true;

	mod->bindings = l_new(uint16_t, cnt);
	if (!mod->bindings)
		return false;

	for (i = 0; i < cnt; ++i) {
		int idx;
		json_object *jvalue;

		jvalue = json_object_array_get_idx(jbindings, i);
		if (!jvalue)
			return false;

		idx = json_object_get_int(jvalue);
		if (!CHECK_KEY_IDX_RANGE(idx))
			return false;

		mod->bindings[i] = (uint16_t) idx;
	}

	return true;
}

static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
{
	int i, num_models;

	num_models = json_object_array_length(jmodels);
	if (!num_models)
		return true;

	for (i = 0; i < num_models; ++i) {
		json_object *jmodel, *jarray, *jvalue;
		struct mesh_db_model *mod;
		uint32_t id;
		int len;
		char *str;

		jmodel = json_object_array_get_idx(jmodels, i);
		if (!jmodel)
			goto fail;

		mod = l_new(struct mesh_db_model, 1);
		if (!ele)
			goto fail;

		json_object_object_get_ex(jmodel, "modelId", &jvalue);
		str = (char *)json_object_get_string(jvalue);

		len = strlen(str);

		if (len != 4 && len != 8)
			goto fail;

		if (len == 4) {
			if (sscanf(str, "%04x", &id) != 1)
				goto fail;

			id |= VENDOR_ID_MASK;
		} else if (len == 8) {
			if (sscanf(str, "%08x", &id) != 1)
				goto fail;
		} else
			goto fail;

		mod->id = id;

		if (len == 8)
			mod->vendor = true;

		json_object_object_get_ex(jmodel, "bind", &jarray);

		if (jarray && (json_object_get_type(jmodels) != json_type_array
					|| !parse_bindings(jarray, mod)))
			goto fail;

		/* TODO add pub/sub */
		l_queue_push_tail(ele->models, mod);
	}

	return true;

fail:
	l_queue_destroy(ele->models, free_model);
	return false;
}

static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
{
	int i, num_ele;

	num_ele = json_object_array_length(jelements);
	if (!num_ele)
		/* Allow "empty" nodes */
		return true;

	node->elements = l_queue_new();
	if (!node->elements)
		return false;

	for (i = 0; i < num_ele; ++i) {
		json_object *jelement;
		json_object *jmodels;
		json_object *jvalue;
		struct mesh_db_element *ele;
		int index;
		char *str;

		jelement = json_object_array_get_idx(jelements, i);
		if (!jelement)
			goto fail;

		if (!get_int(jelement, "elementIndex", &index) ||
								index > num_ele)
			goto fail;

		ele = l_new(struct mesh_db_element, 1);
		if (!ele)
			goto fail;

		ele->index = index;
		ele->models = l_queue_new();
		if (!ele->models)
			goto fail;

		json_object_object_get_ex(jelement, "location", &jvalue);
		str = (char *)json_object_get_string(jvalue);
		if (sscanf(str, "%04hx", &(ele->location)) != 1)
			goto fail;

		json_object_object_get_ex(jelement, "models", &jmodels);

		if (jmodels && (json_object_get_type(jmodels) != json_type_array
				|| !parse_models(jmodels, ele)))
			goto fail;

		l_queue_push_tail(node->elements, ele);
	}

	return true;

fail:
	l_queue_destroy(node->elements, free_element);
	node->elements = NULL;

	return false;
}

static int get_mode(json_object *jvalue)
{
	const char *str;

	str = json_object_get_string(jvalue);
	if (!str)
		return 0xffffffff;

	if (!strncasecmp(str, "disabled", strlen("disabled")))
		return MESH_MODE_DISABLED;

	if (!strncasecmp(str, "enabled", strlen("enabled")))
		return MESH_MODE_ENABLED;

	if (!strncasecmp(str, "unsupported", strlen("unsupported")))
		return MESH_MODE_UNSUPPORTED;

	return 0xffffffff;
}

static void parse_features(json_object *jconfig, struct mesh_db_node *node)
{
	json_object *jvalue, *jrelay;
	int mode, count;
	uint16_t interval;

	json_object_object_get_ex(jconfig, "proxy", &jvalue);
	if (jvalue) {
		mode = get_mode(jvalue);
		if (mode <= MESH_MODE_UNSUPPORTED)
			node->modes.proxy = mode;
	}

	json_object_object_get_ex(jconfig, "friend", &jvalue);
	if (jvalue) {
		mode = get_mode(jvalue);
		if (mode <= MESH_MODE_UNSUPPORTED)
			node->modes.friend = mode;
	}

	json_object_object_get_ex(jconfig, "lowPower", &jvalue);
	if (jvalue) {
		mode = get_mode(jvalue);
		if (mode <= MESH_MODE_UNSUPPORTED)
			node->modes.friend = mode;
	}

	json_object_object_get_ex(jconfig, "beacon", &jvalue);
	if (jvalue) {
		mode = get_mode(jvalue);
		if (mode <= MESH_MODE_ENABLED)
			node->modes.beacon = mode;
	}

	json_object_object_get_ex(jconfig, "relay", &jrelay);
	if (!jrelay)
		return;

	json_object_object_get_ex(jrelay, "mode", &jvalue);
	if (jvalue) {
		mode = get_mode(jvalue);
		if (mode <= MESH_MODE_UNSUPPORTED)
			node->modes.relay.state = mode;
		else
			return;
	} else
		return;

	json_object_object_get_ex(jrelay, "count", &jvalue);
	if (!jvalue)
		return;

	/* TODO: check range */
	count = json_object_get_int(jvalue);
	node->modes.relay.cnt = count;

	json_object_object_get_ex(jrelay, "interval", &jvalue);
	if (!jvalue)
		return;

	/* TODO: check range */
	interval = json_object_get_int(jvalue);
	node->modes.relay.interval = interval;
}

static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
{
	json_object *jvalue;
	char *str;

	/* All the fields in node composition are mandatory */
	json_object_object_get_ex(jcomp, "cid", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (sscanf(str, "%04hx", &node->cid) != 1)
		return false;

	json_object_object_get_ex(jcomp, "pid", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (sscanf(str, "%04hx", &node->pid) != 1)
		return false;

	json_object_object_get_ex(jcomp, "vid", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (sscanf(str, "%04hx", &node->vid) != 1)
		return false;

	json_object_object_get_ex(jcomp, "crpl", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (sscanf(str, "%04hx", &node->crpl) != 1)
		return false;

	return true;
}

static uint16_t get_prov_flags(json_object *jarray, uint16_t max_value)
{
	int i, cnt;
	uint16_t result = 0;

	cnt = json_object_array_length(jarray);
	if (!cnt)
		return 0;

	for (i = 0; i < cnt; ++i) {
		json_object *jvalue;
		int value;

		jvalue = json_object_array_get_idx(jarray, i);
		value = json_object_get_int(jvalue);
		if (value > 16)
			continue;

		if ((1 << value) > max_value)
			continue;

		result |= (1 << value);
	}

	return result;
}

bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
{
	struct mesh_db_node node;
	json_object *jvalue;
	char *str;

	if (!cb) {
		l_info("Node read callback is required");
		return false;
	}

	memset(&node, 0, sizeof(node));

	if (!parse_composition(jnode, &node)) {
		l_info("Failed to parse local node composition");
		return false;
	}

	parse_features(jnode, &node);

	json_object_object_get_ex(jnode, "unicastAddress", &jvalue);
	if (!jvalue) {
		l_info("Bad config: Unicast address must be present");
		return false;
	}

	str = (char *)json_object_get_string(jvalue);
	if (sscanf(str, "%04hx", &node.unicast) != 1)
		return false;

	json_object_object_get_ex(jnode, "defaultTTL", &jvalue);
	if (jvalue) {
		int ttl = json_object_get_int(jvalue);

		if (ttl < 0 || ttl == 1 || ttl > DEFAULT_TTL)
			return false;
		node.ttl = (uint8_t) ttl;
	}

	json_object_object_get_ex(jnode, "sequenceNumber", &jvalue);
	if (jvalue)
		node.seq_number = json_object_get_int(jvalue);

	json_object_object_get_ex(jnode, "elements", &jvalue);
	if (jvalue && json_object_get_type(jvalue) == json_type_array) {
		if (!parse_elements(jvalue, &node))
			return false;
	}

	return cb(&node, user_data);
}

bool mesh_db_read_unprovisioned_device(json_object *jnode, mesh_db_node_cb cb,
								void *user_data)
{
	struct mesh_db_node node;
	json_object *jvalue;
	char *str;

	if (!cb) {
		l_info("Device read callback is required");
		return false;
	}

	memset(&node, 0, sizeof(node));

	if (!parse_composition(jnode, &node)) {
		l_info("Failed to parse local device composition");
		return false;
	}

	parse_features(jnode, &node);

	json_object_object_get_ex(jnode, "elements", &jvalue);
	if (jvalue && json_object_get_type(jvalue) == json_type_array) {
		if (!parse_elements(jvalue, &node))
			return false;
	}

	json_object_object_get_ex(jnode, "UUID", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (!str2hex(str, strlen(str), node.uuid, 16))
		return false;

	return cb(&node, user_data);
}

bool mesh_db_read_prov_info(json_object *jnode, struct mesh_db_prov *prov)
{
	json_object *jprov, *jarray, *jvalue, *jobj;
	int value;
	char *str;

	if (!prov)
		return false;

	json_object_object_get_ex(jnode, "provision", &jprov);
	if (!jprov)
		return false;

	json_object_object_get_ex(jprov, "algorithms", &jarray);
	if (!jarray || json_object_get_type(jarray) != json_type_array)
		return false;

	prov->algorithm = get_prov_flags(jarray, ALG_FIPS_256_ECC);
	if (!prov->algorithm) {
		l_info("At least one algorithm must be indicated");
		return false;
	}

	json_object_object_get_ex(jprov, "outputOOB", &jobj);
	json_object_object_get_ex(jobj, "size", &jvalue);
	value = json_object_get_int(jvalue);
	if (value > 8)
		return false;

	prov->output_oob.size = (uint8_t) value;
	json_object_object_get_ex(jobj, "actions", &jarray);
	if (!jarray || json_object_get_type(jarray) != json_type_array)
		return false;

	prov->output_oob.actions = get_prov_flags(jarray, OOB_OUT_ALPHA);

	json_object_object_get_ex(jprov, "inputOOB", &jobj);
	json_object_object_get_ex(jobj, "size", &jvalue);
	value = json_object_get_int(jvalue);
	if (value > 8)
		return false;

	prov->input_oob.size = (uint8_t) value;
	json_object_object_get_ex(jobj, "actions", &jarray);
	if (!jarray || json_object_get_type(jarray) != json_type_array)
		return false;

	prov->input_oob.actions = get_prov_flags(jarray, OOB_IN_ALPHA);

	json_object_object_get_ex(jprov, "publicType", &jvalue);
	prov->pub_type = (json_object_get_boolean(jvalue)) ? 1 : 0;

	json_object_object_get_ex(jprov, "staticType", &jvalue);
	prov->static_type = (json_object_get_boolean(jvalue)) ? 1 : 0;

	json_object_object_get_ex(jprov, "privateKey", &jvalue);
	if (!jvalue)
		return false;

	str = (char *)json_object_get_string(jvalue);
	if (!str2hex(str, strlen(str), prov->priv_key, 32))
		return false;

	return true;
}

bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
								uint16_t value)
{
	json_object *jstring;
	char buf[5];

	snprintf(buf, 5, "%4.4x", value);
	jstring = json_object_new_string(buf);
	if (!jstring)
		return false;

	json_object_object_add(jobj, desc, jstring);
	return true;
}

bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
{
	json_object *jvalue;

	json_object_object_del(jobj, keyword);

	jvalue = json_object_new_int(value);
	if (!jvalue)
		return false;

	json_object_object_add(jobj, keyword, jvalue);
	return true;
}

bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
{
	json_object *jvalue;

	json_object_object_del(jobj, keyword);

	jvalue = json_object_new_boolean(value);
	if (!jvalue)
		return false;

	json_object_object_add(jobj, keyword, jvalue);
	return true;
}

bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
{
	json_object *jstring;

	switch (value) {
	case MESH_MODE_DISABLED:
		jstring = json_object_new_string("disabled");
		break;
	case MESH_MODE_ENABLED:
		jstring = json_object_new_string("enabled");
		break;
	case MESH_MODE_UNSUPPORTED:
		jstring = json_object_new_string("unsupported");
		break;
	default:
		return false;
	};

	if (!jstring)
		return false;

	json_object_object_add(jobj, keyword, jstring);

	return true;
}

bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
							uint16_t interval)
{
	json_object *jrelay;

	json_object_object_del(jnode, "relay");

	jrelay = json_object_new_object();
	if (jrelay)
		return false;

	if (!mesh_db_write_mode(jrelay, "mode", mode))
		goto fail;

	if (!mesh_db_write_int(jrelay, "count", count))
		goto fail;

	if (!mesh_db_write_int(jrelay, "interval", interval))
		goto fail;

	json_object_object_add(jnode, "relay", jrelay);

	return true;
fail:
	json_object_put(jrelay);
	return false;
}

bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
							uint16_t *interval)
{
	json_object *jretransmit, *jvalue;

	json_object_object_get_ex(jobj, "retransmit", &jretransmit);
	if (!jretransmit)
		return false;

	json_object_object_get_ex(jretransmit, "count", &jvalue);
	if (!jvalue)
		return false;

	*cnt = (uint8_t) json_object_get_int(jvalue);

	json_object_object_get_ex(jretransmit, "interval", &jvalue);
	if (!jvalue)
		return false;

	*interval = (uint16_t) json_object_get_int(jvalue);

	return true;
}

bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
							uint16_t interval)
{
	json_object *jretransmit;

	json_object_object_del(jobj, "retransmit");

	jretransmit = json_object_new_object();
	if (jretransmit)
		return false;

	if (!mesh_db_write_int(jretransmit, "count", cnt))
		goto fail;

	if (!mesh_db_write_int(jretransmit, "interval", interval))
		goto fail;

	json_object_object_add(jobj, "retransmit", jretransmit);

	return true;
fail:
	json_object_put(jretransmit);
	return false;

}

bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
{
	int tmp = update ? 1 : 0;

	if (!mesh_db_write_int(jobj, "IVindex", idx))
		return false;

	if (!mesh_db_write_int(jobj, "IVupdate", tmp))
		return false;

	return true;
}

void mesh_db_remove_property(json_object *jobj, const char *desc)
{
	json_object_object_del(jobj, desc);
}
