/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2017-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 <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>

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

#include "mesh/mesh-defs.h"

#include "mesh/mesh.h"
#include "mesh/node.h"

#include "mesh/net.h"
#include "mesh/appkey.h"
#include "mesh/model.h"
#include "mesh/storage.h"

/*
 * TODO: figure out naming convention to store alternative nodes
 * Mesh storage dir wil be in configure.ac
 */
#define DEVICE_COMPOSITION_FILE "../config/composition.json"
#define NODE_CONGIGURATION_FILE "../config/configuration.json"

static bool read_local_node_cb(struct mesh_db_node *db_node, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_node *node;
	uint32_t seq_number;
	uint16_t crpl;
	uint8_t ttl, mode, cnt, num_ele;
	uint16_t unicast, interval;
	uint8_t *uuid;

	if (!net)
		return false;

	node = node_create_from_storage(net, db_node, true);
	if (!node)
		return false;

	mesh_net_local_node_set(net, node, db_node->provisioner);
	seq_number = node_get_sequence_number(node);
	mesh_net_set_seq_num(net, seq_number);
	ttl = node_default_ttl_get(node);
	mesh_net_set_default_ttl(net, ttl);
	crpl = node_get_crpl(node);
	mesh_net_set_crpl(net, crpl);

	mode = node_proxy_mode_get(node);
	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
		mesh_net_set_proxy_mode(net, mode == MESH_MODE_ENABLED);

	mode = node_friend_mode_get(node);
	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
		mesh_net_set_friend_mode(net, mode == MESH_MODE_ENABLED);

	mode = node_relay_mode_get(node, &cnt, &interval);
	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
		mesh_net_set_relay_mode(net, mode == MESH_MODE_ENABLED, cnt,
								interval);

	mode = node_beacon_mode_get(node);
	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
		mesh_net_set_beacon_mode(net, mode == MESH_MODE_ENABLED);

	unicast = db_node->unicast;
	num_ele = node_get_num_elements(node);

	if (!IS_UNASSIGNED(unicast) &&
		!mesh_net_register_unicast(net, unicast, num_ele))
		return false;

	uuid = node_uuid_get(node);
	if (uuid)
		mesh_net_id_uuid_set(net, uuid);
	return true;
}

static bool read_net_keys_cb(uint16_t idx, uint8_t *key, uint8_t *new_key,
						int phase, void *user_data)
{
	struct mesh_net *net = user_data;

	if (!net)
		return false;

	if (mesh_net_add_key(net, false, idx, key) != MESH_STATUS_SUCCESS)
		return false;
	/* TODO: handle restoring key refresh phase and new keys */

	return true;
}

static bool read_app_keys_cb(uint16_t net_idx, uint16_t app_idx, uint8_t *key,
					uint8_t *new_key, void *user_data)
{
	struct mesh_net *net = user_data;

	if (!net)
		return false;

	return appkey_key_init(net, net_idx, app_idx, key, new_key);
}

static bool parse_local_node(struct mesh_net *net, json_object *jnode)
{
	bool bvalue;
	uint32_t iv_index;
	uint8_t key_buf[16];
	uint8_t cnt;
	uint16_t interval;

	if (mesh_db_read_iv_index(jnode, &iv_index, &bvalue))
		mesh_net_set_iv_index(net, iv_index, bvalue);

	if (mesh_db_read_net_transmit(jnode, &cnt, &interval))
		mesh_net_transmit_params_set(net, cnt, interval);

	/* Node composition/configuration info */
	if (!mesh_db_read_node(jnode, read_local_node_cb, net))
		return false;

	if (!mesh_db_read_net_keys(jnode, read_net_keys_cb, net))
		return false;

	/* TODO: use the actual "primary" network index for this node */
	if (mesh_db_read_device_key(jnode, key_buf) &&
		!node_set_device_key(mesh_net_local_node_get(net), key_buf))
		return false;

	mesh_db_read_app_keys(jnode, read_app_keys_cb, net);

	return true;
}

static bool read_unprov_device_cb(struct mesh_db_node *db_node, void *user_data)
{
	struct mesh_net *net = user_data;
	struct mesh_node *node;
	uint16_t crpl;
	uint8_t *uuid;

	if (!net)
		return false;

	node = node_create_from_storage(net, db_node, true);

	if (!node)
		return false;

	mesh_net_local_node_set(net, node, db_node->provisioner);
	crpl = node_get_crpl(node);
	mesh_net_set_crpl(net, crpl);

	uuid = node_uuid_get(node);
	if (uuid)
		mesh_net_id_uuid_set(net, uuid);

	return true;
}

static bool parse_unprovisioned_device(struct mesh_net *net, json_object *jnode)
{
	struct mesh_db_prov prov;
	struct mesh_net_prov_caps *caps;
	struct mesh_node *node;

	/* Node composition/configuration info */
	if (!mesh_db_read_unprovisioned_device(jnode,
					read_unprov_device_cb, net))
		return false;

	if (!mesh_db_read_prov_info(jnode, &prov))
		return false;

	caps = mesh_net_prov_caps_get(net);
	if (!caps)
		return false;

	node = mesh_net_local_node_get(net);
	if (!node)
		return false;

	caps->num_ele = node_get_num_elements(node);
	l_put_le16(prov.algorithm, &caps->algorithms);
	caps->pub_type = prov.pub_type;
	caps->static_type = prov.static_type;
	caps->output_size = prov.output_oob.size;
	l_put_le16(prov.output_oob.actions, &caps->output_action);
	caps->input_size = prov.input_oob.size;
	l_put_le16(prov.input_oob.actions, &caps->input_action);

	return mesh_net_priv_key_set(net, prov.priv_key);
}

static bool parse_config(struct mesh_net *net, const char *config_name,
							bool unprovisioned)
{
	int fd;
	char *str;
	const char *out;
	struct stat st;
	ssize_t sz;
	json_object *jnode = NULL;
	bool result = false;

	if (!config_name)
		return false;

	fd = open(config_name, O_RDONLY);
	if (!fd)
		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");
		goto done;
	}

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

	mesh_net_jconfig_set(net, jnode);

	if (!unprovisioned)
		result = parse_local_node(net, jnode);
	else
		result = parse_unprovisioned_device(net, jnode);

	if (!result) {
		storage_release(net);
		goto done;
	}

	mesh_net_cfg_file_get(net, &out);
	if (!out)
		mesh_net_cfg_file_set(net, !unprovisioned ?
					config_name : NODE_CONGIGURATION_FILE);
done:
	close(fd);
	if (str)
		l_free(str);

	return result;
}

bool storage_parse_config(struct mesh_net *net, const char *config_name)
{
	bool result = false;
	bool unprovisioned = !config_name;

	if (unprovisioned) {
		result = parse_config(net, DEVICE_COMPOSITION_FILE, true);
		goto done;
	}

	result = parse_config(net, config_name, false);

	if (!result) {
		size_t len = strlen(config_name) + 5;
		char *bak = l_malloc(len);

		/* Fall-back to Backup version */
		strncpy(bak, config_name, len);
		bak = strncat(bak, ".bak", 5);

		remove(config_name);
		rename(bak, config_name);

		result = parse_config(net, config_name, false);

		l_free(bak);
	}

	/* If configuration read fails, try as unprovisioned device */
	if (!result) {
		l_info("Parse configuration failed, trying unprovisioned");
		unprovisioned = true;
		result = parse_config(net, DEVICE_COMPOSITION_FILE, true);
	}

done:
	if (result)
		mesh_net_provisioned_set(net, !unprovisioned);

	return result;
}

bool storage_local_set_ttl(struct mesh_net *net, uint8_t ttl)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_int(jnode, "defaultTTL", ttl);
}

bool storage_local_set_relay(struct mesh_net *net, bool enable,
				uint8_t count, uint8_t interval)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_relay_mode(jnode, enable, count, interval);
}

bool storage_local_set_transmit_params(struct mesh_net *net, uint8_t count,
							uint8_t interval)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_net_transmit(jnode, count, interval);
}

bool storage_local_set_mode(struct mesh_net *net, uint8_t mode,
						const char *mode_name)
{
	json_object *jnode;

	if (!net || !mode_name)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_mode(jnode, mode_name, mode);
}

bool storage_model_bind(struct mesh_net *net, uint16_t addr, uint32_t mod_id,
				uint16_t app_idx, bool unbind)
{
	json_object *jnode;
	bool is_local;

	if (!net)
		return false;

	is_local = mesh_net_is_local_address(net, addr);
	if (is_local) {
		int ele_idx;
		bool is_vendor = (mod_id > 0xffff);

		ele_idx = node_get_element_idx(mesh_net_local_node_get(net),
									addr);
		if (ele_idx < 0)
			return false;

		jnode = mesh_net_jconfig_get(net);
		if (!jnode)
			return false;

		if (unbind)
			return mesh_db_model_binding_del(jnode, ele_idx,
						is_vendor, mod_id, app_idx);
		else
			return mesh_db_model_binding_add(jnode, ele_idx,
						is_vendor, mod_id, app_idx);
	}

	/* TODO: write remote node bindings to provisioner DB */
	return false;
}

bool storage_local_app_key_add(struct mesh_net *net, uint16_t net_idx,
			uint16_t app_idx, const uint8_t key[16], bool update)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_app_key_add(jnode, net_idx, app_idx, key, update);
}

bool storage_local_app_key_del(struct mesh_net *net, uint16_t net_idx,
					uint16_t app_idx)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_app_key_del(jnode, net_idx, app_idx);

}

bool storage_local_net_key_add(struct mesh_net *net, uint16_t net_idx,
					const uint8_t key[16], int phase)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_net_key_add(jnode, net_idx, key, phase);
}

bool storage_local_net_key_del(struct mesh_net *net, uint16_t net_idx)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_net_key_del(jnode, net_idx);
}

bool storage_local_set_iv_index(struct mesh_net *net, uint32_t iv_index,
								bool update)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_iv_index(jnode, iv_index, update);
}

bool storage_local_set_device_key(struct mesh_net *net, uint8_t dev_key[16])
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_device_key(jnode, dev_key);
}

bool storage_local_set_unicast(struct mesh_net *net, uint16_t unicast)
{
	json_object *jnode;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	return mesh_db_write_uint16_hex(jnode, "unicastAddress", unicast);
}

bool storage_local_write_sequence_number(struct mesh_net *net, uint32_t seq)
{
	json_object *jnode;
	const char *cfg_file;
	bool result;

	if (!net)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	result = mesh_db_write_int(jnode, "sequenceNumber", seq);
	if (!result)
		return false;

	result = mesh_net_cfg_file_get(net, &cfg_file);
	if (result && cfg_file)
		result = storage_save_config(net, cfg_file, false, NULL, NULL);

	return result;
}

static bool save_config(struct mesh_net *net, const char *config_name)
{
	FILE *outfile;
	const char *str;
	json_object *jnode;
	bool result = false;

	if (!net || !config_name)
		return false;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	outfile = fopen(config_name, "w");
	if (!outfile) {
		l_error("Failed to save configuration to %s", config_name);
		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;
}

struct write_info {
	const char *config_name;
	struct mesh_net *net;
	void *user_data;
	mesh_status_func_t cb;
};

static void idle_save_config(void *user_data)
{
	struct write_info *info = user_data;
	size_t len = strlen(info->config_name) + 5;
	char *tmp = l_malloc(len);
	char *bak = l_malloc(len);
	bool result = false;

	strncpy(tmp, info->config_name, len);
	strncpy(bak, info->config_name, len);
	tmp = strncat(tmp, ".tmp", 5);
	bak = strncat(bak, ".bak", 5);
	remove(tmp);

	l_debug("Storage-Wrote");
	result = save_config(info->net, tmp);

	if (result) {
		remove(bak);
		rename(info->config_name, bak);
		rename(tmp, info->config_name);
	}

	remove(tmp);
	l_free(tmp);
	l_free(bak);

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

	l_free(info);
}

bool storage_save_config(struct mesh_net *net, const char *config_name,
			bool no_wait, mesh_status_func_t cb, void *user_data)
{
	struct write_info *info;

	info = l_new(struct write_info, 1);
	if (!info)
		return false;

	info->net = net;
	info->config_name = config_name;
	info->cb = cb;
	info->user_data = user_data;

	if (no_wait)
		idle_save_config(info);
	l_idle_oneshot(idle_save_config, info, NULL);

	return true;
}

bool storage_save_new_config(struct mesh_net *net, const char *config_name,
					mesh_status_func_t cb, void *user_data)
{
	json_object *jnode;

	jnode = mesh_net_jconfig_get(net);
	if (!jnode)
		return false;

	mesh_db_remove_property(jnode, "provision");

	return storage_save_config(net, config_name, false, cb, user_data);
}

void storage_release(struct mesh_net *net)
{
	json_object *jnode;

	jnode = mesh_net_jconfig_get(net);
	if (jnode)
		json_object_put(jnode);

	mesh_net_jconfig_set(net, NULL);
}
