/*
 * Copyright (c) 2019 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr/settings/settings.h>

#include <errno.h>
#include <zephyr/sys/printk.h>

#if IS_ENABLED(CONFIG_SETTINGS_FILE)
#include <zephyr/fs/fs.h>
#include <zephyr/fs/littlefs.h>
#endif

#define STORAGE_PARTITION	storage_partition
#define STORAGE_PARTITION_ID	FIXED_PARTITION_ID(STORAGE_PARTITION)

#define GAMMA_DEFAULT_VAl 0
#define FAIL_MSG "fail (err %d)\n"
#define SECTION_BEGIN_LINE \
	"\n=================================================\n"
/* Default values are assigned to settings values consuments
 * All of them will be overwritten if storage contain proper key-values
 */
uint8_t angle_val;
uint64_t length_val = 100;
uint16_t length_1_val = 40;
uint32_t length_2_val = 60;
int32_t voltage_val = -3000;
char source_name_val[6] = "";

int alpha_handle_set(const char *name, size_t len, settings_read_cb read_cb,
		  void *cb_arg);
int alpha_handle_commit(void);
int alpha_handle_export(int (*cb)(const char *name,
			       const void *value, size_t val_len));

int beta_handle_set(const char *name, size_t len, settings_read_cb read_cb,
		  void *cb_arg);
int beta_handle_commit(void);
int beta_handle_export(int (*cb)(const char *name,
			       const void *value, size_t val_len));
int beta_handle_get(const char *name, char *val, int val_len_max);

/* dynamic main tree handler */
struct settings_handler alph_handler = {
		.name = "alpha",
		.h_get = NULL,
		.h_set = alpha_handle_set,
		.h_commit = alpha_handle_commit,
		.h_export = alpha_handle_export
};

/* static subtree handler */
SETTINGS_STATIC_HANDLER_DEFINE(beta, "alpha/beta", beta_handle_get,
			       beta_handle_set, beta_handle_commit,
			       beta_handle_export);

int alpha_handle_set(const char *name, size_t len, settings_read_cb read_cb,
		  void *cb_arg)
{
	const char *next;
	size_t next_len;
	int rc;

	if (settings_name_steq(name, "angle/1", &next) && !next) {
		if (len != sizeof(angle_val)) {
			return -EINVAL;
		}
		rc = read_cb(cb_arg, &angle_val, sizeof(angle_val));
		printk("<alpha/angle/1> = %d\n", angle_val);
		return 0;
	}

	next_len = settings_name_next(name, &next);

	if (!next) {
		return -ENOENT;
	}

	if (!strncmp(name, "length", next_len)) {
		next_len = settings_name_next(name, &next);

		if (!next) {
			rc = read_cb(cb_arg, &length_val, sizeof(length_val));
			printk("<alpha/length> = %" PRId64 "\n", length_val);
			return 0;
		}

		if (!strncmp(next, "1", next_len)) {
			rc = read_cb(cb_arg, &length_1_val,
				     sizeof(length_1_val));
			printk("<alpha/length/1> = %d\n", length_1_val);
			return 0;
		}

		if (!strncmp(next, "2", next_len)) {
			rc = read_cb(cb_arg, &length_2_val,
				     sizeof(length_2_val));
			printk("<alpha/length/2> = %d\n", length_2_val);
			return 0;
		}

		return -ENOENT;
	}

	return -ENOENT;
}

int beta_handle_set(const char *name, size_t len, settings_read_cb read_cb,
		  void *cb_arg)
{
	const char *next;
	size_t name_len;
	int rc;

	name_len = settings_name_next(name, &next);

	if (!next) {
		if (!strncmp(name, "voltage", name_len)) {
			rc = read_cb(cb_arg, &voltage_val, sizeof(voltage_val));
			printk("<alpha/beta/voltage> = %d\n", voltage_val);
			return 0;
		}

		if (!strncmp(name, "source", name_len)) {
			if (len > sizeof(source_name_val) - 1) {
				printk("<alpha/beta/source> is not compatible "
				       "with the application\n");
				return -EINVAL;
			}
			rc = read_cb(cb_arg, source_name_val,
				     sizeof(source_name_val));
			if (rc < 0) {
				return rc;
			} else if (rc > 0) {
				printk("<alpha/beta/source> = %s\n",
				       source_name_val);
			}
			return 0;
		}
	}

	return -ENOENT;
}

int alpha_handle_commit(void)
{
	printk("loading all settings under <alpha> handler is done\n");
	return 0;
}

int alpha_handle_export(int (*cb)(const char *name,
			       const void *value, size_t val_len))
{
	printk("export keys under <alpha> handler\n");
	(void)cb("alpha/angle/1", &angle_val, sizeof(angle_val));
	(void)cb("alpha/length", &length_val, sizeof(length_val));
	(void)cb("alpha/length/1", &length_1_val, sizeof(length_1_val));
	(void)cb("alpha/length/2", &length_2_val, sizeof(length_2_val));

	return 0;
}

int beta_handle_export(int (*cb)(const char *name,
			       const void *value, size_t val_len))
{
	printk("export keys under <beta> handler\n");
	(void)cb("alpha/beta/voltage", &voltage_val, sizeof(voltage_val));
	(void)cb("alpha/beta/source", source_name_val, strlen(source_name_val) +
						       1);

	return 0;
}

int beta_handle_commit(void)
{
	printk("loading all settings under <beta> handler is done\n");
	return 0;
}

int beta_handle_get(const char *name, char *val, int val_len_max)
{
	const char *next;

	if (settings_name_steq(name, "source", &next) && !next) {
		val_len_max = MIN(val_len_max, strlen(source_name_val));
		memcpy(val, source_name_val, val_len_max);
		return val_len_max;
	}

	return -ENOENT;
}

static void example_save_and_load_basic(void)
{
	int i, rc;
	int32_t val_s32;

	printk(SECTION_BEGIN_LINE);
	printk("basic load and save using registered handlers\n");
	/* load all key-values at once
	 * In case a key-value doesn't exist in the storage
	 * default values should be assigned to settings consuments variable
	 * before any settings load call
	 */
	printk("\nload all key-value pairs using registered handlers\n");
	settings_load();

	val_s32 = voltage_val - 25;
	/* save certain key-value directly*/
	printk("\nsave <alpha/beta/voltage> key directly: ");
	rc = settings_save_one("alpha/beta/voltage", (const void *)&val_s32,
			       sizeof(val_s32));
	if (rc) {
		printk(FAIL_MSG, rc);
	}

	printk("OK.\n");

	printk("\nload <alpha/beta> key-value pairs using registered "
	       "handlers\n");
	settings_load_subtree("alpha/beta");

	/* save only modified values
	 * or those that were not saved
	 * before
	 */
	i = strlen(source_name_val);
	if (i < sizeof(source_name_val) - 1) {
		source_name_val[i] = 'a' + i;
		source_name_val[i + 1] = 0;
	} else {
		source_name_val[0] = 0;
	}

	angle_val += 1;

	printk("\nsave all key-value pairs using registered handlers\n");
	settings_save();

	if (++length_1_val > 100) {
		length_1_val = 0;
	}

	if (--length_2_val > 100) {
		length_2_val = 100;
	}

	/*---------------------------
	 * save only modified values
	 * or those that were deleted
	 * before
	 */
	printk("\nload all key-value pairs using registered handlers\n");
	settings_save();
}

struct direct_length_data {
	uint64_t length;
	uint16_t length_1;
	uint32_t length_2;
};

static int direct_loader(const char *name, size_t len, settings_read_cb read_cb,
			  void *cb_arg, void *param)
{
	const char *next;
	size_t name_len;
	int rc;
	struct direct_length_data *dest = (struct direct_length_data *)param;

	printk("direct load: ");

	name_len = settings_name_next(name, &next);

	if (name_len == 0) {
		rc = read_cb(cb_arg, &(dest->length), sizeof(dest->length));
		printk("<alpha/length>\n");
		return 0;
	}

	name_len = settings_name_next(name, &next);
	if (next) {
		printk("nothing\n");
		return -ENOENT;
	}

	if (!strncmp(name, "1", name_len)) {
		rc = read_cb(cb_arg, &(dest->length_1), sizeof(dest->length_1));
		printk("<alpha/length/1>\n");
		return 0;
	}

	if (!strncmp(name, "2", name_len)) {
		rc = read_cb(cb_arg, &(dest->length_2), sizeof(dest->length_2));
		printk("<alpha/length/2>\n");
		return 0;
	}

	printk("nothing\n");
	return -ENOENT;
}

static void example_direct_load_subtree(void)
{
	struct direct_length_data dld;
	int rc;

	/* load subtree directly using call-specific handler `direct_loader'
	 * This handler loads subtree values to call-specific structure of type
	 * 'direct_length_data`.
	 */
	printk(SECTION_BEGIN_LINE);
	printk("loading subtree to destination provided by the caller\n\n");
	rc = settings_load_subtree_direct("alpha/length", direct_loader,
					  (void *)&dld);
	if (rc == 0) {
		printk("  direct.length = %" PRId64 "\n", dld.length);
		printk("  direct.length_1 = %d\n", dld.length_1);
		printk("  direct.length_2 = %d\n", dld.length_2);
	} else {
		printk("  direct load fails unexpectedly\n");
	}
}

struct direct_immediate_value {
	size_t len;
	void *dest;
	uint8_t fetched;
};

static int direct_loader_immediate_value(const char *name, size_t len,
					 settings_read_cb read_cb, void *cb_arg,
					 void *param)
{
	const char *next;
	size_t name_len;
	int rc;
	struct direct_immediate_value *one_value =
					(struct direct_immediate_value *)param;

	name_len = settings_name_next(name, &next);

	if (name_len == 0) {
		if (len == one_value->len) {
			rc = read_cb(cb_arg, one_value->dest, len);
			if (rc >= 0) {
				one_value->fetched = 1;
				printk("immediate load: OK.\n");
				return 0;
			}

			printk(FAIL_MSG, rc);
			return rc;
		}
		return -EINVAL;
	}

	/* other keys aren't served by the callback
	 * Return success in order to skip them
	 * and keep storage processing.
	 */
	return 0;
}

int load_immediate_value(const char *name, void *dest, size_t len)
{
	int rc;
	struct direct_immediate_value dov;

	dov.fetched = 0;
	dov.len = len;
	dov.dest = dest;

	rc = settings_load_subtree_direct(name, direct_loader_immediate_value,
					  (void *)&dov);
	if (rc == 0) {
		if (!dov.fetched) {
			rc = -ENOENT;
		}
	}

	return rc;
}

static void example_without_handler(void)
{
	uint8_t val_u8;
	int rc;

	printk(SECTION_BEGIN_LINE);
	printk("Service a key-value pair without dedicated handlers\n\n");
	rc = load_immediate_value("gamma", &val_u8, sizeof(val_u8));
	if (rc == -ENOENT) {
		val_u8 = GAMMA_DEFAULT_VAl;
		printk("<gamma> = %d (default)\n", val_u8);
	} else if (rc == 0) {
		printk("<gamma> = %d\n", val_u8);
	} else {
		printk("unexpected"FAIL_MSG, rc);
	}

	val_u8++;

	printk("save <gamma> key directly: ");
	rc = settings_save_one("gamma", (const void *)&val_u8,
			       sizeof(val_u8));
	if (rc) {
		printk(FAIL_MSG, rc);
	} else {
		printk("OK.\n");
	}
}

static void example_initialization(void)
{
	int rc;

#if IS_ENABLED(CONFIG_SETTINGS_FILE)
	FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage);

	/* mounting info */
	static struct fs_mount_t littlefs_mnt = {
	.type = FS_LITTLEFS,
	.fs_data = &cstorage,
	.storage_dev = (void *)STORAGE_PARTITION_ID,
	.mnt_point = "/ff"
	};

	rc = fs_mount(&littlefs_mnt);
	if (rc != 0) {
		printk("mounting littlefs error: [%d]\n", rc);
	} else {

		rc = fs_unlink(CONFIG_SETTINGS_FILE_PATH);
		if ((rc != 0) && (rc != -ENOENT)) {
			printk("can't delete config file%d\n", rc);
		} else {
			printk("FS initialized: OK\n");
		}
	}
#endif

	rc = settings_subsys_init();
	if (rc) {
		printk("settings subsys initialization: fail (err %d)\n", rc);
		return;
	}

	printk("settings subsys initialization: OK.\n");

	rc = settings_register(&alph_handler);
	if (rc) {
		printk("subtree <%s> handler registered: fail (err %d)\n",
		       alph_handler.name, rc);
	}

	printk("subtree <%s> handler registered: OK\n", alph_handler.name);
	printk("subtree <alpha/beta> has static handler\n");
}

static void example_delete(void)
{
	uint64_t val_u64;
	int rc;

	printk(SECTION_BEGIN_LINE);
	printk("Delete a key-value pair\n\n");

	rc = load_immediate_value("alpha/length", &val_u64, sizeof(val_u64));
	if (rc == 0) {
		printk("  <alpha/length> value exist in the storage\n");
	}

	printk("delete <alpha/length>: ");
	rc = settings_delete("alpha/length");
	if (rc) {
		printk(FAIL_MSG, rc);
	} else {
		printk("OK.\n");
	}

	rc = load_immediate_value("alpha/length", &val_u64, sizeof(val_u64));
	if (rc == -ENOENT) {
		printk("  Can't to load the <alpha/length> value as "
		       "expected\n");
	}
}

void example_runtime_usage(void)
{
	int rc;
	uint8_t injected_str[sizeof(source_name_val)] = "RT";

	printk(SECTION_BEGIN_LINE);
	printk("Inject the value to the setting destination in runtime\n\n");

	rc = settings_runtime_set("alpha/beta/source", (void *) injected_str,
				  strlen(injected_str) + 1);

	printk("injected <alpha/beta/source>: ");
	if (rc) {
		printk(FAIL_MSG, rc);
	} else {
		printk("OK.\n");
	}

	printk("  The settings destination off the key <alpha/beta/source> has "
	       "got value: \"%s\"\n\n", source_name_val);

	/* set settings destination value "by hand" for next example */
	(void) strcpy(source_name_val, "rtos");

	printk(SECTION_BEGIN_LINE);
	printk("Read a value from the setting destination in runtime\n\n");

	rc = settings_runtime_get("alpha/beta/source", (void *) injected_str,
				  strlen(injected_str) + 1);
	printk("fetched <alpha/beta/source>: ");
	if (rc < 0) {
		printk(FAIL_MSG, rc);
	} else {
		printk("OK.\n");
	}

	printk("  String value \"%s\" was retrieved from the settings "
	       "destination off the key <alpha/beta/source>\n",
	       source_name_val);
}

void main(void)
{

	int i;

	printk("\n*** Settings usage example ***\n\n");

	/* settings initialization */
	example_initialization();

	for (i = 0; i < 6; i++) {
		printk("\n##############\n");
		printk("# iteration %d", i);
		printk("\n##############\n");

		/*---------------------------------------------
		 * basic save and load using registered handler
		 */
		example_save_and_load_basic();

		/*-------------------------------------------------
		 *load subtree directly using call-specific handler
		 */
		example_direct_load_subtree();

		/*-------------------------
		 * delete certain kay-value
		 */
		example_delete();

		/*---------------------------------------
		 * a key-value without dedicated handler
		 */
		example_without_handler();
	}

	/*------------------------------------------------------
	 * write and read settings destination using runtime API
	 */
	example_runtime_usage();

	printk("\n*** THE END  ***\n");
}
