/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2018-2019  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

#define _GNU_SOURCE
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <ftw.h>
#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <sys/time.h>

#include <ell/ell.h>
#include <json-c/json.h>

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

/* To prevent local node JSON cache thrashing, minimum update times */
#define MIN_SEQ_CACHE_TRIGGER	32
#define MIN_SEQ_CACHE_VALUE	(2 * 32)
#define MIN_SEQ_CACHE_TIME	(5 * 60)

#define CHECK_KEY_IDX_RANGE(x) ((x) <= 4095)

struct mesh_config {
	json_object *jnode;
	char *node_dir_path;
	uint8_t uuid[16];
	uint32_t write_seq;
	struct timeval write_time;
	struct l_queue *idles;
};

struct write_info {
	struct mesh_config *cfg;
	void *user_data;
	mesh_config_status_func_t cb;
};

static const char *cfgnode_name = "/node.json";
static const char *bak_ext = ".bak";
static const char *tmp_ext = ".tmp";

static bool save_config(json_object *jnode, const char *fname)
{
	FILE *outfile;
	const char *str;
	bool result = false;

	outfile = fopen(fname, "w");
	if (!outfile) {
		l_error("Failed to save configuration to %s", fname);
		return false;
	}

	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);

	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
		l_warn("Incomplete write of mesh configuration");
	else
		result = true;

	fclose(outfile);

	return result;
}

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_u64_value(json_object *jobj, const char *desc,
					const uint8_t u64[8])
{
	json_object *jstring;
	char hexstr[17];

	hex2str((uint8_t *) u64, 8, hexstr, 17);
	jstring = json_object_new_string(hexstr);
	if (!jstring)
		return false;

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

static bool add_key_value(json_object *jobj, 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_del(jobj, desc);
	json_object_object_add(jobj, desc, jstring);
	return true;
}

static int get_element_index(json_object *jnode, uint16_t ele_addr)
{
	json_object *jvalue, *jelements;
	uint16_t addr, num_ele;
	char *str;

	if (!json_object_object_get_ex(jnode, "unicastAddress", &jvalue))
		return -1;

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

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

	num_ele = json_object_array_length(jelements);

	if (ele_addr >= addr + num_ele || ele_addr < addr)
		return -1;

	return ele_addr - addr;
}

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 (!json_object_object_get_ex(jnode, "elements", &jelements))
		return NULL;

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

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

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

	if (!vendor) {
		snprintf(buf, 5, "%4.4x", (uint16_t)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);
		if (!json_object_object_get_ex(jmodel, "modelId", &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 void jarray_string_del(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 && !strncmp(str, str_entry, len)) {
			json_object_array_del_idx(jarray, i, 1);
			return;
		}

	}
}

static bool get_key_index(json_object *jobj, const char *keyword,
								uint16_t *index)
{
	int idx;

	if (!get_int(jobj, keyword, &idx))
		return false;

	if (!CHECK_KEY_IDX_RANGE(idx))
		return false;

	*index = (uint16_t) idx;
	return true;
}

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;
		uint16_t jidx;

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

		if (jidx == idx)
			return jentry;
	}

	return NULL;
}

static void jarray_key_del(json_object *jarray, int16_t idx)
{
	int i, sz = json_object_array_length(jarray);

	for (i = 0; i < sz; ++i) {
		json_object *jentry;
		uint16_t nidx;

		jentry = json_object_array_get_idx(jarray, i);

		if (get_key_index(jentry, "index", &nidx) && nidx == idx) {
			json_object_array_del_idx(jarray, i, 1);
			return;
		}
	}
}

static bool read_unicast_address(json_object *jobj, uint16_t *unicast)
{
	json_object *jvalue;
	char *str;

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

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

	return true;
}

static bool read_default_ttl(json_object *jobj, uint8_t *ttl)
{
	json_object *jvalue;
	int val;

	/* defaultTTL is optional */
	if (!json_object_object_get_ex(jobj, "defaultTTL", &jvalue))
		return true;

	val = json_object_get_int(jvalue);

	if (!val && errno == EINVAL)
		return false;

	if (val < 0 || val == 1 || val > TTL_MASK)
		return false;

	*ttl = (uint8_t) val;

	return true;
}

static bool read_seq_number(json_object *jobj, uint32_t *seq_number)
{
	json_object *jvalue;
	int val;

	/* sequenceNumber is optional */
	if (!json_object_object_get_ex(jobj, "sequenceNumber", &jvalue))
		return true;

	val = json_object_get_int(jvalue);

	if (!val && errno == EINVAL)
		return false;

	if (val < 0 || val > SEQ_MASK + 1)
		return false;

	*seq_number = (uint32_t) val;

	return true;
}

static bool 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;
}

static bool read_token(json_object *jobj, uint8_t token[8])
{
	json_object *jvalue;
	char *str;

	if (!token)
		return false;

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

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

	return true;
}

static bool 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))
		return false;

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

	return true;
}

static bool read_comp_pages(json_object *jobj, struct mesh_config_node *node)
{
	json_object *jarray, *jentry;
	struct mesh_config_comp_page *page;
	int len;
	int i;

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

	if (json_object_get_type(jarray) != json_type_array)
		return false;

	len = json_object_array_length(jarray);

	for (i = 0; i < len; i++) {
		size_t clen;
		char *str;

		jentry = json_object_array_get_idx(jarray, i);
		str = (char *)json_object_get_string(jentry);
		clen = strlen(str);

		if (clen < ((MIN_COMP_SIZE * 2) + 1))
			continue;

		clen = (clen / 2) - 1;

		page = l_malloc(sizeof(struct mesh_config_comp_page) + clen);

		if (!str2hex(str + 2, clen * 2, page->data, clen))
			goto parse_fail;

		if (sscanf(str, "%02hhx", &page->page_num) != 1)
			goto parse_fail;

		page->len = clen;

		l_queue_push_tail(node->pages, page);
	}

	return true;

parse_fail:
	l_free(page);
	return false;
}

static bool read_app_keys(json_object *jobj, struct mesh_config_node *node)
{
	json_object *jarray;
	int len;
	int i;

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

	if (json_object_get_type(jarray) != json_type_array)
		return false;

	/* Allow empty AppKey array */
	len = json_object_array_length(jarray);
	if (!len)
		return true;

	for (i = 0; i < len; ++i) {
		json_object *jtemp, *jvalue;
		char *str;
		struct mesh_config_appkey *appkey;

		appkey = l_new(struct mesh_config_appkey, 1);

		jtemp = json_object_array_get_idx(jarray, i);

		if (!get_key_index(jtemp, "index", &appkey->app_idx))
			goto fail;

		if (!get_key_index(jtemp, "boundNetKey", &appkey->net_idx))
			goto fail;

		if (!json_object_object_get_ex(jtemp, "key", &jvalue))
			goto fail;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), appkey->new_key, 16))
			goto fail;

		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue))
			str = (char *)json_object_get_string(jvalue);

		if (!str2hex(str, strlen(str), appkey->key, 16))
			goto fail;

		l_queue_push_tail(node->appkeys, appkey);
	}

	return true;
fail:
	l_queue_destroy(node->appkeys, l_free);
	node->appkeys = NULL;

	return false;
}

static bool read_net_keys(json_object *jobj, struct mesh_config_node *node)
{
	json_object *jarray;
	int len;
	int i;

	/* At least one NetKey must be present for a provisioned node */
	if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
		return false;

	if (json_object_get_type(jarray) != json_type_array)
		return false;

	len = json_object_array_length(jarray);
	if (!len)
		return false;

	for (i = 0; i < len; ++i) {
		json_object *jtemp, *jvalue;
		char *str;
		struct mesh_config_netkey *netkey;

		netkey = l_new(struct mesh_config_netkey, 1);

		jtemp = json_object_array_get_idx(jarray, i);

		if (!get_key_index(jtemp, "index", &netkey->idx))
			goto fail;

		if (!json_object_object_get_ex(jtemp, "key", &jvalue))
			goto fail;

		str = (char *)json_object_get_string(jvalue);
		if (!str2hex(str, strlen(str), netkey->new_key, 16))
			goto fail;

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

		if (netkey->phase > KEY_REFRESH_PHASE_TWO)
			goto fail;

		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
			if (netkey->phase == KEY_REFRESH_PHASE_NONE)
				goto fail;

			str = (char *)json_object_get_string(jvalue);
		}

		if (!str2hex(str, strlen(str), netkey->key, 16))
			goto fail;

		l_queue_push_tail(node->netkeys, netkey);
	}

	return true;
fail:
	l_queue_destroy(node->netkeys, l_free);
	node->netkeys = NULL;

	return false;
}

static bool write_int(json_object *jobj, const char *desc, int val)
{
	json_object *jvalue;

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

	json_object_object_del(jobj, desc);
	json_object_object_add(jobj, desc, jvalue);
	return true;
}

bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t idx,
							const uint8_t key[16])
{
	json_object *jnode, *jarray = NULL, *jentry = NULL;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	l_debug("netKey %4.4x", idx);
	json_object_object_get_ex(jnode, "netKeys", &jarray);
	if (jarray)
		jentry = get_key_object(jarray, idx);

	/* Do not allow direct overwrite */
	if (jentry)
		return false;

	jentry = json_object_new_object();
	if (!jentry)
		return false;

	if (!write_int(jentry, "index", idx))
		goto fail;

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

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

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

	json_object_array_add(jarray, jentry);

	return save_config(jnode, cfg->node_dir_path);

fail:
	if (jentry)
		json_object_put(jentry);

	return false;
}

bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
							const uint8_t key[16])
{
	json_object *jnode, *jarray, *jentry, *jstring;
	const char *str;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
		return false;

	jentry = get_key_object(jarray, idx);
	/* Net key must be already recorded */
	if (!jentry)
		return false;

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

	str = json_object_get_string(jstring);
	jstring = json_object_new_string(str);
	json_object_object_add(jentry, "oldKey", jstring);
	json_object_object_del(jentry, "key");

	if (!add_key_value(jentry, "key", key))
		return false;

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

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
{
	json_object *jnode, *jarray;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

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

	jarray_key_del(jarray, idx);

	if (!json_object_array_length(jarray))
		json_object_object_del(jnode, "netKeys");

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
{
	if (!cfg || !add_key_value(cfg->jnode, "deviceKey", key))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
{
	if (!cfg || !add_u64_value(cfg->jnode, "token", token))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
					uint16_t app_idx, const uint8_t key[16])
{
	json_object *jnode, *jarray = NULL, *jentry = NULL;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	json_object_object_get_ex(jnode, "appKeys", &jarray);
	if (jarray)
		jentry = get_key_object(jarray, app_idx);

	/* Do not allow direct overrwrite */
	if (jentry)
		return false;

	jentry = json_object_new_object();
	if (!jentry)
		return false;

	if (!write_int(jentry, "index", app_idx))
		goto fail;

	if (!write_int(jentry, "boundNetKey", net_idx))
		goto fail;

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

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

	json_object_array_add(jarray, jentry);

	return save_config(jnode, cfg->node_dir_path);

fail:

	if (jentry)
		json_object_put(jentry);

	return false;
}

bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
							const uint8_t key[16])
{
	json_object *jnode, *jarray, *jentry = NULL, *jstring = NULL;
	const char *str;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

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

	/* The key entry should exist if the key is updated */
	jentry = get_key_object(jarray, app_idx);
	if (!jentry)
		return false;

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

	str = json_object_get_string(jstring);
	jstring = json_object_new_string(str);
	json_object_object_add(jentry, "oldKey", jstring);

	json_object_object_del(jentry, "key");

	/* TODO: "Rewind" if add_key_value fails */
	if (!add_key_value(jentry, "key", key))
		return false;

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
								uint16_t idx)
{
	json_object *jnode, *jarray;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

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

	jarray_key_del(jarray, idx);

	if (!json_object_array_length(jarray))
		json_object_object_del(jnode, "appKeys");

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_model_binding_add(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
							uint16_t app_idx)
{
	json_object *jnode, *jmodel, *jstring, *jarray = NULL;
	int ele_idx;
	char buf[5];

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

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

	json_object_object_get_ex(jmodel, "bind", &jarray);
	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 save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_model_binding_del(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
							uint16_t app_idx)
{
	json_object *jnode, *jmodel, *jarray;
	int ele_idx;
	char buf[5];

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	if (!json_object_object_get_ex(jmodel, "bind", &jarray))
		return true;

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

	jarray_string_del(jarray, buf, 4);

	if (!json_object_array_length(jarray))
		json_object_object_del(jmodel, "bind");

	return save_config(jnode, cfg->node_dir_path);
}

static void free_model(void *data)
{
	struct mesh_config_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_config_element *ele = data;

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

static bool parse_bindings(json_object *jarray, struct mesh_config_model *mod)
{
	int cnt;
	int i;

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

	mod->num_bindings = cnt;

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

	mod->bindings = l_new(uint16_t, cnt);

	for (i = 0; i < cnt; ++i) {
		uint16_t idx;
		const char *str;
		json_object *jvalue;

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

		str = json_object_get_string(jvalue);

		if (sscanf(str, "%04hx", &idx) != 1)
			return false;

		if (!CHECK_KEY_IDX_RANGE(idx))
			return false;

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

	return true;
}

static struct mesh_config_pub *parse_model_publication(json_object *jpub)
{
	json_object *jvalue;
	struct mesh_config_pub *pub;
	int len, value;
	char *str;

	if (!json_object_object_get_ex(jpub, "address", &jvalue))
		return NULL;

	str = (char *)json_object_get_string(jvalue);
	len = strlen(str);
	pub = l_new(struct mesh_config_pub, 1);

	switch (len) {
	case 4:
		if (sscanf(str, "%04hx", &pub->addr) != 1)
			goto fail;
		break;
	case 32:
		if (!str2hex(str, len, pub->virt_addr, 16))
			goto fail;

		pub->virt = true;
		break;
	default:
		goto fail;
	}

	if (!get_key_index(jpub, "index", &pub->idx))
		goto fail;

	if (!get_int(jpub, "ttl", &value))
		goto fail;
	pub->ttl = (uint8_t) value;

	if (!get_int(jpub, "period", &value))
		goto fail;
	pub->period = value;

	if (!get_int(jpub, "credentials", &value))
		goto fail;
	pub->credential = (uint8_t) value;

	if (!json_object_object_get_ex(jpub, "retransmit", &jvalue))
		goto fail;

	if (!get_int(jvalue, "count", &value))
		goto fail;
	pub->cnt = (uint8_t) value;

	if (!get_int(jvalue, "interval", &value))
		goto fail;
	pub->interval = (uint8_t) value;

	return pub;

fail:
	l_free(pub);
	return NULL;
}

static bool parse_model_subscriptions(json_object *jsubs,
						struct mesh_config_model *mod)
{
	struct mesh_config_sub *subs;
	int i, cnt;

	if (json_object_get_type(jsubs) != json_type_array)
		return NULL;

	cnt = json_object_array_length(jsubs);
	/* Allow empty array */
	if (!cnt)
		return true;

	subs = l_new(struct mesh_config_sub, cnt);

	for (i = 0; i < cnt; ++i) {
		char *str;
		int len;
		json_object *jvalue;

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

		str = (char *)json_object_get_string(jvalue);
		len = strlen(str);

		switch (len) {
		case 4:
			if (sscanf(str, "%04hx", &subs[i].addr.grp) != 1)
				goto fail;
		break;
		case 32:
			if (!str2hex(str, len, subs[i].addr.label, 16))
				goto fail;
			subs[i].virt = true;
			break;
		default:
			goto fail;
		}
	}

	mod->num_subs = cnt;
	mod->subs = subs;

	return true;
fail:
	l_free(subs);
	return false;
}

static bool parse_models(json_object *jmodels, struct mesh_config_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_config_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_config_model, 1);

		if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
			goto fail;

		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;

		} else if (len == 8) {
			if (sscanf(str, "%08x", &id) != 1)
				goto fail;
			mod->vendor = true;
		} else
			goto fail;

		mod->id = id;

		if (json_object_object_get_ex(jmodel, "bind", &jarray)) {
			if (json_object_get_type(jarray) != json_type_array ||
					!parse_bindings(jarray, mod))
				goto fail;
		}

		if (json_object_object_get_ex(jmodel, "pubEnabled", &jvalue))
			mod->pub_enabled = json_object_get_boolean(jvalue);
		else
			mod->pub_enabled = true;

		if (json_object_object_get_ex(jmodel, "subEnabled", &jvalue))
			mod->sub_enabled = json_object_get_boolean(jvalue);
		else
			mod->sub_enabled = true;

		if (json_object_object_get_ex(jmodel, "publish", &jvalue)) {
			mod->pub = parse_model_publication(jvalue);
			if (!mod->pub)
				goto fail;
		}

		if (json_object_object_get_ex(jmodel, "subscribe", &jarray)) {
			if (!parse_model_subscriptions(jarray, mod))
				goto fail;
		}

		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 *jelems, struct mesh_config_node *node)
{
	int i, num_ele;

	if (json_object_get_type(jelems) != json_type_array)
		return false;

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

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

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

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

		ele = l_new(struct mesh_config_element, 1);
		ele->index = index;
		ele->models = l_queue_new();
		l_queue_push_tail(node->elements, ele);

		if (!json_object_object_get_ex(jelement, "location", &jvalue))
			goto fail;

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

		if (json_object_object_get_ex(jelement, "models", &jmodels)) {
			if (json_object_get_type(jmodels) != json_type_array ||
						!parse_models(jmodels, ele))
				goto fail;
		}
	}

	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_config_node *node)
{
	json_object *jvalue, *jrelay;
	int mode, count;
	uint16_t interval;

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

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

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

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

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

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

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

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

	if (!json_object_object_get_ex(jrelay, "interval", &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_config_node *node)
{
	json_object *jvalue;
	char *str;

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

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

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

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

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

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

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

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

	return true;
}

static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node)
{
	json_object *jrtx, *jvalue;
	uint16_t interval;
	uint8_t cnt;

	if (!json_object_object_get_ex(jobj, "retransmit", &jrtx))
		return true;

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

	/* TODO: add range checking */
	cnt = (uint8_t) json_object_get_int(jvalue);

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

	interval = (uint16_t) json_object_get_int(jvalue);

	node->net_transmit = l_new(struct mesh_config_transmit, 1);
	node->net_transmit->count = cnt;
	node->net_transmit->interval = interval;

	return true;
}

static bool read_node(json_object *jnode, struct mesh_config_node *node)
{
	json_object *jvalue;

	if (!read_iv_index(jnode, &node->iv_index, &node->iv_update)) {
		l_info("Failed to read IV index");
		return false;
	}

	if (!read_token(jnode, node->token)) {
		l_info("Failed to read node token");
		return false;
	}

	if (!read_device_key(jnode, node->dev_key)) {
		l_info("Failed to read node device key");
		return false;
	}

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

	parse_features(jnode, node);

	if (!read_unicast_address(jnode, &node->unicast)) {
		l_info("Failed to parse unicast address");
		return false;
	}

	if (!read_default_ttl(jnode, &node->ttl)) {
		l_info("Failed to parse default ttl");
		return false;
	}

	if (!read_seq_number(jnode, &node->seq_number)) {
		l_info("Failed to parse sequence number");
		return false;
	}

	/* Check for required "elements" property */
	if (!json_object_object_get_ex(jnode, "elements", &jvalue))
		return false;

	if (!read_net_transmit(jnode, node)) {
		l_info("Failed to read node net transmit parameters");
		return false;
	}

	if (!read_net_keys(jnode, node)) {
		l_info("Failed to read net keys");
		return false;
	}

	if (!read_app_keys(jnode, node)) {
		l_info("Failed to read app keys");
		return false;
	}

	if (!read_comp_pages(jnode, node)) {
		l_info("Failed to read Composition Pages");
		return false;
	}

	if (!parse_elements(jvalue, node)) {
		l_info("Failed to parse elements");
		return false;
	}

	return true;
}

static bool 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_del(jobj, desc);
	json_object_object_add(jobj, desc, jstring);
	return true;
}

static bool write_uint32_hex(json_object *jobj, const char *desc, uint32_t val)
{
	json_object *jstring;
	char buf[9];

	snprintf(buf, 9, "%8.8x", val);
	jstring = json_object_new_string(buf);
	if (!jstring)
		return false;

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

static const char *mode_to_string(int mode)
{
	switch (mode) {
	case MESH_MODE_DISABLED:
		return "disabled";
	case MESH_MODE_ENABLED:
		return "enabled";
	default:
		return "unsupported";
	}
}

static bool write_mode(json_object *jobj, const char *desc, int value)
{
	json_object *jstring;

	jstring = json_object_new_string(mode_to_string(value));

	if (!jstring)
		return false;

	json_object_object_del(jobj, desc);
	json_object_object_add(jobj, desc, jstring);

	return true;
}

bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
								int value)
{
	if (!cfg || !write_mode(cfg->jnode, keyword, value))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

static bool write_relay_mode(json_object *jobj, uint8_t mode,
					uint8_t count, uint16_t interval)
{
	json_object *jrelay;

	json_object_object_del(jobj, "relay");

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

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

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

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

	json_object_object_add(jobj, "relay", jrelay);

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

bool mesh_config_write_unicast(struct mesh_config *cfg, uint16_t unicast)
{
	if (!cfg || !write_uint16_hex(cfg->jnode, "unicastAddress", unicast))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
					uint8_t count, uint16_t interval)
{

	if (!cfg || !write_relay_mode(cfg->jnode, mode, count, interval))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
							uint16_t interval)
{
	json_object *jnode, *jrtx;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	jrtx = json_object_new_object();
	if (!jrtx)
		return false;

	if (!write_int(jrtx, "count", cnt))
		goto fail;

	if (!write_int(jrtx, "interval", interval))
		goto fail;

	json_object_object_del(jnode, "retransmit");
	json_object_object_add(jnode, "retransmit", jrtx);

	return save_config(cfg->jnode, cfg->node_dir_path);

fail:
	json_object_put(jrtx);
	return false;

}

bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
								bool update)
{
	json_object *jnode;
	int tmp = update ? 1 : 0;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	if (!write_int(jnode, "IVindex", idx))
		return false;

	if (!write_int(jnode, "IVupdate", tmp))
		return false;

	return save_config(jnode, cfg->node_dir_path);
}

static void add_model(void *a, void *b)
{
	struct mesh_config_model *mod = a;
	json_object *jmodels = b, *jmodel, *jval;

	jmodel = json_object_new_object();
	if (!jmodel)
		return;

	if (!mod->vendor)
		write_uint16_hex(jmodel, "modelId",
						(uint16_t) mod->id);
	else
		write_uint32_hex(jmodel, "modelId", mod->id);

	jval = json_object_new_boolean(mod->sub_enabled);
	json_object_object_add(jmodel, "subEnabled", jval);

	jval = json_object_new_boolean(mod->pub_enabled);
	json_object_object_add(jmodel, "pubEnabled", jval);

	json_object_array_add(jmodels, jmodel);
}

/* Add unprovisioned node (local) */
static struct mesh_config *create_config(const char *cfg_path,
					const uint8_t uuid[16],
					struct mesh_config_node *node)
{
	struct mesh_config_modes *modes = &node->modes;
	const struct l_queue_entry *entry;
	json_object *jnode, *jelems;
	struct mesh_config *cfg;

	if (!cfg_path || !node)
		return NULL;

	jnode = json_object_new_object();

	/* CID, PID, VID, crpl */
	if (!write_uint16_hex(jnode, "cid", node->cid))
		return NULL;

	if (!write_uint16_hex(jnode, "pid", node->pid))
		return NULL;

	if (!write_uint16_hex(jnode, "vid", node->vid))
		return NULL;

	if (!write_uint16_hex(jnode, "crpl", node->crpl))
		return NULL;

	/* Features: relay, LPN, friend, proxy*/
	if (!write_relay_mode(jnode, modes->relay.state,
				modes->relay.cnt, modes->relay.interval))
		return NULL;

	if (!write_mode(jnode, "lowPower", modes->lpn))
		return NULL;

	if (!write_mode(jnode, "friend", modes->friend))
		return NULL;

	if (!write_mode(jnode, "proxy", modes->proxy))
		return NULL;

	/* Beaconing state */
	if (!write_mode(jnode, "beacon", modes->beacon))
		return NULL;

	/* Sequence number */
	json_object_object_add(jnode, "sequenceNumber",
					json_object_new_int(node->seq_number));

	/* Default TTL */
	json_object_object_add(jnode, "defaultTTL",
						json_object_new_int(node->ttl));

	/* Elements */
	jelems = json_object_new_array();
	if (!jelems)
		return NULL;

	entry = l_queue_get_entries(node->elements);

	for (; entry; entry = entry->next) {
		struct mesh_config_element *ele = entry->data;
		json_object *jelement, *jmodels;

		jelement = json_object_new_object();

		if (!jelement) {
			json_object_put(jelems);
			return NULL;
		}

		write_int(jelement, "elementIndex", ele->index);
		write_uint16_hex(jelement, "location", ele->location);
		json_object_array_add(jelems, jelement);

		/* Models */
		if (l_queue_isempty(ele->models))
			continue;

		jmodels = json_object_new_array();
		if (!jmodels) {
			json_object_put(jelems);
			return NULL;
		}

		json_object_object_add(jelement, "models", jmodels);
		l_queue_foreach(ele->models, add_model, jmodels);
	}

	json_object_object_add(jnode, "elements", jelems);

	cfg = l_new(struct mesh_config, 1);

	cfg->jnode = jnode;
	memcpy(cfg->uuid, uuid, 16);
	cfg->node_dir_path = l_strdup(cfg_path);
	cfg->write_seq = node->seq_number;
	cfg->idles = l_queue_new();
	gettimeofday(&cfg->write_time, NULL);

	return cfg;
}

struct mesh_config *mesh_config_create(const char *cfgdir_name,
		const uint8_t uuid[16], struct mesh_config_node *db_node)
{
	char uuid_buf[33];
	char name_buf[PATH_MAX];
	struct mesh_config *cfg;
	size_t max_len = strlen(cfgnode_name) + strlen(bak_ext);

	if (!hex2str((uint8_t *) uuid, 16, uuid_buf, sizeof(uuid_buf)))
		return NULL;

	snprintf(name_buf, PATH_MAX, "%s/%s", cfgdir_name, uuid_buf);

	if (strlen(name_buf) + max_len >= PATH_MAX)
		return NULL;

	/* Create a new directory and node.json file */
	if (mkdir(name_buf, 0755) != 0)
		return NULL;

	snprintf(name_buf, PATH_MAX, "%s/%s%s", cfgdir_name, uuid_buf,
								cfgnode_name);
	l_debug("New node config %s", name_buf);

	cfg = create_config(name_buf, uuid, db_node);
	if (!cfg)
		return NULL;

	if (!mesh_config_save(cfg, true, NULL, NULL)) {
		mesh_config_release(cfg);
		return NULL;
	}

	return cfg;
}

static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
{
	json_object *jarray;
	int i, len;

	/* Clean up all the bound appkeys */
	if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
		return;

	len = json_object_array_length(jarray);

	for (i = 0; i < len; ++i) {
		json_object *jentry;
		uint16_t idx;

		jentry = json_object_array_get_idx(jarray, i);

		if (!get_key_index(jentry, "boundNetKey", &idx))
			continue;

		if (idx != net_idx)
			continue;

		json_object_object_del(jentry, "oldKey");

		if (!get_key_index(jentry, "index", &idx))
			continue;
	}

}

bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
								uint8_t phase)
{
	json_object *jnode, *jarray, *jentry = NULL;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	if (json_object_object_get_ex(jnode, "netKeys", &jarray))
		jentry = get_key_object(jarray, idx);

	if (!jentry)
		return false;

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

	if (phase == KEY_REFRESH_PHASE_NONE) {
		json_object_object_del(jentry, "oldKey");
		finish_key_refresh(jnode, idx);
	}

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr,
					uint32_t mod_id, bool vendor,
					struct mesh_config_pub *pub)
{
	json_object *jnode, *jmodel, *jpub, *jrtx;
	bool res;
	int ele_idx;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	json_object_object_del(jmodel, "publish");

	jpub = json_object_new_object();
	if (!jpub)
		return false;

	if (pub->virt)
		res = add_key_value(jpub, "address", pub->virt_addr);
	else
		res = write_uint16_hex(jpub, "address", pub->addr);

	if (!res)
		goto fail;

	if (!write_int(jpub, "index", pub->idx))
		goto fail;

	if (!write_int(jpub, "ttl", pub->ttl))
		goto fail;

	if (!write_int(jpub, "period", pub->period))
		goto fail;

	if (!write_int(jpub, "credentials", pub->credential ? 1 : 0))
		goto fail;

	jrtx = json_object_new_object();
	if (!jrtx)
		goto fail;

	if (!write_int(jrtx, "count", pub->cnt))
		goto fail;

	if (!write_int(jrtx, "interval", pub->interval))
		goto fail;

	json_object_object_add(jpub, "retransmit", jrtx);
	json_object_object_add(jmodel, "publish", jpub);

	return save_config(jnode, cfg->node_dir_path);

fail:
	json_object_put(jpub);
	return false;
}

static bool delete_model_property(json_object *jnode, uint16_t ele_addr,
			uint32_t mod_id, bool vendor, const char *keyword)
{
	json_object *jmodel;
	int ele_idx;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	json_object_object_del(jmodel, keyword);

	return true;
}

bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t addr,
						uint32_t mod_id, bool vendor)
{
	if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
								"publish"))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

static void del_page(json_object *jarray, uint8_t page)
{
	char buf[3];
	int i, len;

	if (!jarray)
		return;

	snprintf(buf, 3, "%2.2x", page);

	len = json_object_array_length(jarray);

	for (i = 0; i < len; i++) {
		json_object *jentry;
		char *str;

		jentry = json_object_array_get_idx(jarray, i);
		str = (char *)json_object_get_string(jentry);

		/* Delete matching page(s) */
		if (!memcmp(str, buf, 2))
			json_object_array_del_idx(jarray, i, 1);
	}
}

bool mesh_config_comp_page_add(struct mesh_config *cfg, uint8_t page,
						uint8_t *data, uint16_t size)
{
	json_object *jnode, *jstring, *jarray = NULL;
	char *buf;
	int len;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	json_object_object_get_ex(jnode, "pages", &jarray);

	len = (size * 2) + 3;
	buf = l_malloc(len);
	snprintf(buf, len, "%2.2x", page);
	hex2str(data, size, buf + 2, len - 2);

	if (jarray && jarray_has_string(jarray, buf, len)) {
		l_free(buf);
		return true;
	} else if (!jarray) {
		jarray = json_object_new_array();
		json_object_object_add(jnode, "pages", jarray);
	} else
		del_page(jarray, page);

	jstring = json_object_new_string(buf);
	json_object_array_add(jarray, jstring);
	l_free(buf);

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_comp_page_mv(struct mesh_config *cfg, uint8_t old, uint8_t nw)
{
	json_object *jnode, *jarray = NULL;
	uint8_t *data;
	char *str;
	char old_buf[3];
	int i, len, dlen = 0;
	bool status = true;

	if (!cfg || old == nw)
		return false;

	jnode = cfg->jnode;

	json_object_object_get_ex(jnode, "pages", &jarray);

	if (!jarray)
		return false;

	snprintf(old_buf, 3, "%2.2x", old);
	data = l_malloc(MAX_MSG_LEN);

	len = json_object_array_length(jarray);

	for (i = 0; i < len; i++) {
		json_object *jentry;

		jentry = json_object_array_get_idx(jarray, i);
		str = (char *)json_object_get_string(jentry);

		/* Delete matching page(s) but save data*/
		if (!memcmp(str, old_buf, 2)) {
			dlen = strlen(str + 2);
			str2hex(str + 2, dlen, data, MAX_MSG_LEN);
			dlen /= 2;
			json_object_array_del_idx(jarray, i, 1);
		}
	}

	if (dlen)
		status = mesh_config_comp_page_add(cfg, nw, data, dlen);

	l_free(data);

	return status;
}

bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
						struct mesh_config_sub *sub)
{
	json_object *jnode, *jmodel, *jstring, *jarray = NULL;
	int ele_idx, len;
	char buf[33];

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	if (!sub->virt) {
		snprintf(buf, 5, "%4.4x", sub->addr.grp);
		len = 4;
	} else {
		hex2str(sub->addr.label, 16, buf, 33);
		len = 32;
	}

	json_object_object_get_ex(jmodel, "subscribe", &jarray);
	if (jarray && jarray_has_string(jarray, buf, len))
		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, "subscribe", jarray);
	}

	json_object_array_add(jarray, jstring);

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
						struct mesh_config_sub *sub)
{
	json_object *jnode, *jmodel, *jarray;
	char buf[33];
	int len, ele_idx;

	if (!cfg)
		return false;

	jnode = cfg->jnode;

	ele_idx = get_element_index(jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	if (!json_object_object_get_ex(jmodel, "subscribe", &jarray))
		return true;

	if (!sub->virt) {
		snprintf(buf, 5, "%4.4x", sub->addr.grp);
		len = 4;
	} else {
		hex2str(sub->addr.label, 16, buf, 33);
		len = 32;
	}

	jarray_string_del(jarray, buf, len);

	if (!json_object_array_length(jarray))
		json_object_object_del(jmodel, "subscribe");

	return save_config(jnode, cfg->node_dir_path);
}

bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
						uint32_t mod_id, bool vendor)
{
	if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
								"subscribe"))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_model_pub_enable(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
						bool enable)
{
	json_object *jmodel, *jval;
	int ele_idx;

	if (!cfg)
		return false;

	ele_idx = get_element_index(cfg->jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	json_object_object_del(jmodel, "pubDisabled");

	jval = json_object_new_boolean(!enable);
	json_object_object_add(jmodel, "pubDisabled", jval);

	if (!enable)
		json_object_object_del(jmodel, "publish");

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_model_sub_enable(struct mesh_config *cfg, uint16_t ele_addr,
						uint32_t mod_id, bool vendor,
						bool enable)
{
	json_object *jmodel, *jval;
	int ele_idx;

	if (!cfg)
		return false;

	ele_idx = get_element_index(cfg->jnode, ele_addr);
	if (ele_idx < 0)
		return false;

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

	json_object_object_del(jmodel, "subEnabled");

	jval = json_object_new_boolean(enable);
	json_object_object_add(jmodel, "subEnabled", jval);

	if (!enable)
		json_object_object_del(jmodel, "subscribe");

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq,
								bool cache)
{
	int value = 0;
	uint32_t cached = 0;

	if (!cfg)
		return false;

	if (!cache) {
		if (!write_int(cfg->jnode, "sequenceNumber", seq))
			return false;

		return mesh_config_save(cfg, true, NULL, NULL);
	}

	/* If resetting seq to Zero, make sure cached value reset as well */
	if (seq && get_int(cfg->jnode, "sequenceNumber", &value))
		cached = (uint32_t)value;

	/*
	 * When sequence number approaches value stored on disk, calculate
	 * average time between sequence number updates, then overcommit the
	 * sequence number by MIN_SEQ_CACHE_TIME seconds worth of traffic or
	 * MIN_SEQ_CACHE_VALUE (whichever is greater) to avoid frequent writes
	 * to disk and to protect against crashes.
	 *
	 * The real value will be saved when daemon shuts down properly.
	 */
	if (seq + MIN_SEQ_CACHE_TRIGGER >= cached) {
		struct timeval now;
		struct timeval elapsed;
		uint64_t elapsed_ms;

		gettimeofday(&now, NULL);
		timersub(&now, &cfg->write_time, &elapsed);
		elapsed_ms = elapsed.tv_sec * 1000 + elapsed.tv_usec / 1000;

		/*
		 * If time since last write is zero, this means that
		 * idle_save_config is already pending, so we don't need to do
		 * anything.
		 */
		if (!elapsed_ms)
			return true;

		cached = seq + (seq - cfg->write_seq) *
					1000 * MIN_SEQ_CACHE_TIME / elapsed_ms;

		if (cached < seq + MIN_SEQ_CACHE_VALUE)
			cached = seq + MIN_SEQ_CACHE_VALUE;

		/* Cap the seq cache maximum to fixed out-of-range value.
		 * If daemon restarts with out-of-range value, no packets
		 * are to be sent until IV Update procedure completes.
		 */
		if (cached > SEQ_MASK)
			cached = SEQ_MASK + 1;

		cfg->write_seq = seq;

		/* Don't rewrite NVM storage if unchanged */
		if (value == (int) cached)
			return true;

		l_debug("Seq Cache: %d -> %d", seq, cached);

		if (!write_int(cfg->jnode, "sequenceNumber", cached))
		    return false;

		return mesh_config_save(cfg, false, NULL, NULL);
	}

	return true;
}

bool mesh_config_write_ttl(struct mesh_config *cfg, uint8_t ttl)
{
	if (!cfg || !write_int(cfg->jnode, "defaultTTL", ttl))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_update_company_id(struct mesh_config *cfg, uint16_t cid)
{
	if (!cfg || !write_uint16_hex(cfg->jnode, "cid", cid))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_update_product_id(struct mesh_config *cfg, uint16_t pid)
{
	if (!cfg || !write_uint16_hex(cfg->jnode, "pid", pid))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_update_version_id(struct mesh_config *cfg, uint16_t vid)
{
	if (!cfg || !write_uint16_hex(cfg->jnode, "vid", vid))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

bool mesh_config_update_crpl(struct mesh_config *cfg, uint16_t crpl)
{
	if (!cfg || !write_uint16_hex(cfg->jnode, "crpl", crpl))
		return false;

	return save_config(cfg->jnode, cfg->node_dir_path);
}

static bool load_node(const char *fname, const uint8_t uuid[16],
				mesh_config_node_func_t cb, void *user_data)
{
	int fd;
	char *str;
	struct stat st;
	ssize_t sz;
	bool result = false;
	json_object *jnode;
	struct mesh_config_node node;

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

	l_info("Loading configuration from %s", fname);

	fd = open(fname, O_RDONLY);
	if (fd < 0)
		return false;

	if (fstat(fd, &st) == -1) {
		close(fd);
		return false;
	}

	str = (char *) l_new(char, st.st_size + 1);
	if (!str) {
		close(fd);
		return false;
	}

	sz = read(fd, str, st.st_size);
	if (sz != st.st_size) {
		l_error("Failed to read configuration file %s", fname);
		goto done;
	}

	jnode = json_tokener_parse(str);
	if (!jnode)
		goto done;

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

	node.elements = l_queue_new();
	node.netkeys = l_queue_new();
	node.appkeys = l_queue_new();
	node.pages = l_queue_new();

	result = read_node(jnode, &node);

	if (result) {
		struct mesh_config *cfg = l_new(struct mesh_config, 1);

		cfg->jnode = jnode;
		memcpy(cfg->uuid, uuid, 16);
		cfg->node_dir_path = l_strdup(fname);
		cfg->write_seq = node.seq_number;
		cfg->idles = l_queue_new();
		gettimeofday(&cfg->write_time, NULL);

		result = cb(&node, uuid, cfg, user_data);

		if (!result) {
			l_free(cfg->idles);
			l_free(cfg->node_dir_path);
			l_free(cfg);
		}
	}

	/* Done with the node: free resources */
	l_free(node.net_transmit);
	l_queue_destroy(node.netkeys, l_free);
	l_queue_destroy(node.appkeys, l_free);
	l_queue_destroy(node.pages, l_free);
	l_queue_destroy(node.elements, free_element);

	if (!result)
		json_object_put(jnode);

done:
	close(fd);
	if (str)
		l_free(str);

	return result;
}

static void release_idle(void *data)
{
	struct l_idle *idle = data;

	l_idle_remove(idle);
}

void mesh_config_release(struct mesh_config *cfg)
{
	if (!cfg)
		return;

	l_queue_destroy(cfg->idles, release_idle);

	l_free(cfg->node_dir_path);
	json_object_put(cfg->jnode);
	l_free(cfg);
}

static void idle_save_config(struct l_idle *idle, void *user_data)
{
	struct write_info *info = user_data;
	char *fname_tmp, *fname_bak, *fname_cfg;
	bool result = false;

	fname_cfg = info->cfg->node_dir_path;
	fname_tmp = l_strdup_printf("%s%s", fname_cfg, tmp_ext);
	fname_bak = l_strdup_printf("%s%s", fname_cfg, bak_ext);
	remove(fname_tmp);

	result = save_config(info->cfg->jnode, fname_tmp);

	if (result) {
		remove(fname_bak);
		rename(fname_cfg, fname_bak);
		rename(fname_tmp, fname_cfg);
	}

	remove(fname_tmp);

	l_free(fname_tmp);
	l_free(fname_bak);

	gettimeofday(&info->cfg->write_time, NULL);

	if (info->cb)
		info->cb(info->user_data, result);

	if (idle) {
		l_queue_remove(info->cfg->idles, idle);
		l_idle_remove(idle);
	}

	l_free(info);

}

bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
				mesh_config_status_func_t cb, void *user_data)
{
	struct write_info *info;

	if (!cfg)
		return false;

	info = l_new(struct write_info, 1);
	info->cfg = cfg;
	info->cb = cb;
	info->user_data = user_data;

	if (no_wait) {
		idle_save_config(NULL, info);
	} else {
		struct l_idle *idle;

		idle = l_idle_create(idle_save_config, info, NULL);
		l_queue_push_tail(cfg->idles, idle);
	}

	return true;
}

bool mesh_config_load_nodes(const char *cfgdir_name, mesh_config_node_func_t cb,
								void *user_data)
{
	DIR *cfgdir;
	struct dirent *entry;
	size_t path_len = strlen(cfgdir_name) + strlen(cfgnode_name) +
								strlen(bak_ext);

	create_dir(cfgdir_name);
	cfgdir = opendir(cfgdir_name);
	if (!cfgdir) {
		l_error("Failed to open mesh node storage directory: %s",
								cfgdir_name);
		return false;
	}

	while ((entry = readdir(cfgdir)) != NULL) {
		char *dirname, *fname, *bak;
		uint8_t uuid[16];
		size_t node_len;

		if (entry->d_type != DT_DIR)
			continue;

		/* Check path length */
		node_len = strlen(entry->d_name);

		if (path_len + node_len + 1 >= PATH_MAX)
			continue;

		if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
			continue;

		dirname = l_strdup_printf("%s/%s", cfgdir_name, entry->d_name);
		fname = l_strdup_printf("%s%s", dirname, cfgnode_name);

		if (!load_node(fname, uuid, cb, user_data)) {

			/* Fall-back to Backup version */
			bak = l_strdup_printf("%s%s", fname, bak_ext);

			if (load_node(bak, uuid, cb, user_data)) {
				remove(fname);
				rename(bak, fname);
			}

			l_free(bak);
		}

		l_free(fname);
		l_free(dirname);
	}

	closedir(cfgdir);

	return true;
}

void mesh_config_destroy_nvm(struct mesh_config *cfg)
{
	char *node_dir, *node_name;
	char uuid[33];

	if (!cfg)
		return;

	node_dir = dirname(cfg->node_dir_path);
	l_debug("Delete node config %s", node_dir);

	if (!hex2str(cfg->uuid, 16, uuid, sizeof(uuid)))
		return;

	node_name = basename(node_dir);

	/* Make sure path name of node follows expected guidelines */
	if (strcmp(node_name, uuid))
		return;

	del_path(node_dir);
}
