/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 * Copyright (c) 2015 Runtime Inc
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <stdbool.h>
#include <zephyr/zephyr.h>

#include <zephyr/fs/fs.h>

#include <zephyr/settings/settings.h>
#include "settings/settings_file.h"
#include "settings_priv.h"

#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL);

int settings_backend_init(void);
void settings_mount_fs_backend(struct settings_file *cf);

static int settings_file_load(struct settings_store *cs,
			      const struct settings_load_arg *arg);
static int settings_file_save(struct settings_store *cs, const char *name,
			      const char *value, size_t val_len);
static void *settings_fs_storage_get(struct settings_store *cs);

static const struct settings_store_itf settings_file_itf = {
	.csi_load = settings_file_load,
	.csi_save = settings_file_save,
	.csi_storage_get = settings_fs_storage_get
};

/*
 * Register a file to be a source of configuration.
 */
int settings_file_src(struct settings_file *cf)
{
	if (!cf->cf_name) {
		return -EINVAL;
	}
	cf->cf_store.cs_itf = &settings_file_itf;
	settings_src_register(&cf->cf_store);

	return 0;
}

/*
 * Register a file to be a destination of configuration.
 */
int settings_file_dst(struct settings_file *cf)
{
	if (!cf->cf_name) {
		return -EINVAL;
	}
	cf->cf_store.cs_itf = &settings_file_itf;
	settings_dst_register(&cf->cf_store);

	return 0;
}

/**
 * @brief Check if there is any duplicate of the current setting
 *
 * This function checks if there is any duplicated data further in the buffer.
 *
 * @param entry_ctx Current entry context
 * @param name      The name of the current entry
 *
 * @retval false No duplicates found
 * @retval true  Duplicate found
 */
static bool settings_file_check_duplicate(
				  const struct line_entry_ctx *entry_ctx,
				  const char * const name)
{
	struct line_entry_ctx entry2_ctx = *entry_ctx;

	/* Searching the duplicates */
	while (settings_next_line_ctx(&entry2_ctx) == 0) {
		char name2[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
		size_t name2_len;

		if (entry2_ctx.len == 0) {
			break;
		}

		if (settings_line_name_read(name2, sizeof(name2), &name2_len,
					    &entry2_ctx)) {
			continue;
		}
		name2[name2_len] = '\0';

		if (!strcmp(name, name2)) {
			return true;
		}
	}
	return false;
}

static int read_entry_len(const struct line_entry_ctx *entry_ctx, off_t off)
{
	if (off >= entry_ctx->len) {
		return 0;
	}
	return entry_ctx->len - off;
}

static int settings_file_load_priv(struct settings_store *cs, line_load_cb cb,
				   void *cb_arg, bool filter_duplicates)
{
	struct settings_file *cf = (struct settings_file *)cs;
	struct fs_file_t file;
	int lines;
	int rc;

	struct line_entry_ctx entry_ctx = {
		.stor_ctx = (void *)&file,
		.seek = 0,
		.len = 0 /* unknown length */
	};

	lines = 0;

	fs_file_t_init(&file);

	rc = fs_open(&file, cf->cf_name, FS_O_CREATE | FS_O_RDWR);
	if (rc != 0) {
		return -EINVAL;
	}

	while (1) {
		char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
		size_t name_len;
		bool pass_entry = true;

		rc = settings_next_line_ctx(&entry_ctx);
		if (rc || entry_ctx.len == 0) {
			break;
		}

		rc = settings_line_name_read(name, sizeof(name), &name_len,
					     &entry_ctx);

		if (rc || name_len == 0) {
			break;
		}
		name[name_len] = '\0';

		if (filter_duplicates &&
		    (!read_entry_len(&entry_ctx, name_len+1) ||
		     settings_file_check_duplicate(&entry_ctx, name))) {
			pass_entry = false;
		}
		/*name, val-read_cb-ctx, val-off*/
		/* take into account '=' separator after the name */
		if (pass_entry) {
			cb(name, (void *)&entry_ctx, name_len + 1, cb_arg);
		}
		lines++;
	}

	rc = fs_close(&file);
	cf->cf_lines = lines;

	return rc;
}

/*
 * Called to load configuration items.
 */
static int settings_file_load(struct settings_store *cs,
			      const struct settings_load_arg *arg)
{
	return settings_file_load_priv(cs,
				       settings_line_load_cb,
				       (void *)arg,
				       true);
}

static void settings_tmpfile(char *dst, const char *src, char *pfx)
{
	int len;
	int pfx_len;

	len = strlen(src);
	pfx_len = strlen(pfx);
	if (len + pfx_len >= SETTINGS_FILE_NAME_MAX) {
		len = SETTINGS_FILE_NAME_MAX - pfx_len - 1;
	}
	memcpy(dst, src, len);
	memcpy(dst + len, pfx, pfx_len);
	dst[len + pfx_len] = '\0';
}

static int settings_file_create_or_replace(struct fs_file_t *zfp,
					   const char *file_name)
{
	struct fs_dirent entry;

	if (fs_stat(file_name, &entry) == 0) {
		if (entry.type == FS_DIR_ENTRY_FILE) {
			if (fs_unlink(file_name)) {
				return -EIO;
			}
		} else {
			return -EISDIR;
		}
	}

	return fs_open(zfp, file_name, FS_O_CREATE | FS_O_RDWR);
}

/*
 * Try to compress configuration file by keeping unique names only.
 */
static int settings_file_save_and_compress(struct settings_file *cf,
			   const char *name, const char *value,
			   size_t val_len)
{
	int rc, rc2;
	struct fs_file_t rf;
	struct fs_file_t wf;
	char tmp_file[SETTINGS_FILE_NAME_MAX];
	char name1[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN];
	char name2[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN];
	struct line_entry_ctx loc1 = {
		.stor_ctx = &rf,
		.seek = 0,
		.len = 0 /* unknown length */
	};

	struct line_entry_ctx loc2;

	struct line_entry_ctx loc3 = {
		.stor_ctx = &wf
	};

	int copy;
	int lines;
	size_t new_name_len;
	size_t val1_off;

	fs_file_t_init(&rf);
	fs_file_t_init(&wf);

	if (fs_open(&rf, cf->cf_name, FS_O_CREATE | FS_O_RDWR) != 0) {
		return -ENOEXEC;
	}

	settings_tmpfile(tmp_file, cf->cf_name, ".cmp");

	if (settings_file_create_or_replace(&wf, tmp_file)) {
		fs_close(&rf);
		return -ENOEXEC;
	}

	lines = 0;
	new_name_len = strlen(name);

	while (1) {
		rc = settings_next_line_ctx(&loc1);

		if (rc || loc1.len == 0) {
			/* try to amend new value to the compressed file */
			break;
		}

		rc = settings_line_name_read(name1, sizeof(name1), &val1_off,
					     &loc1);
		if (rc) {
			/* try to process next line */
			continue;
		}

		if (val1_off + 1 == loc1.len) {
			/* Lack of a value so the record is a deletion-record */
			/* No sense to copy empty entry from */
			/* the oldest sector */
			continue;
		}

		/* avoid copping value which will be overwritten by new value*/
		if ((val1_off == new_name_len) &&
		    !memcmp(name1, name, val1_off)) {
			continue;
		}

		loc2 = loc1;

		copy = 1;
		while (1) {
			size_t val2_off;

			rc = settings_next_line_ctx(&loc2);

			if (rc || loc2.len == 0) {
				/* try to amend new value to */
				/* the compressed file */
				break;
			}

			rc = settings_line_name_read(name2, sizeof(name2),
						     &val2_off, &loc2);
			if (rc) {
				/* try to process next line */
				continue;
			}
			if ((val1_off == val2_off) &&
			    !memcmp(name1, name2, val1_off)) {
				copy = 0; /* newer version doesn't exist */
				break;
			}
		}
		if (!copy) {
			continue;
		}

		loc2 = loc1;
		loc2.len += 2;
		loc2.seek -= 2;
		rc = settings_line_entry_copy(&loc3, 0, &loc2, 0, loc2.len);
		if (rc) {
			/* compressed file might be corrupted */
			goto end_rolback;
		}

		lines++;
	}

	/* at last store the new value */
	rc = settings_line_write(name, value, val_len, 0, &loc3);
	if (rc) {
		/* compressed file might be corrupted */
		goto end_rolback;
	}

	rc = fs_close(&wf);
	rc2 = fs_close(&rf);
	if (rc == 0 && rc2 == 0 && fs_unlink(cf->cf_name) == 0) {
		if (fs_rename(tmp_file, cf->cf_name)) {
			return -ENOENT;
		}
		cf->cf_lines = lines + 1;
	} else {
		rc = -EIO;
	}
	/*
	 * XXX at settings_file_load(), look for .cmp if actual file does not
	 * exist.
	 */
	return 0;
end_rolback:
	(void)fs_close(&wf);
	if (fs_close(&rf) == 0) {
		(void)fs_unlink(tmp_file);
	}
	return -EIO;

}

static int settings_file_save_priv(struct settings_store *cs, const char *name,
				   const char *value, size_t val_len)
{
	struct settings_file *cf = (struct settings_file *)cs;
	struct line_entry_ctx entry_ctx;
	struct fs_file_t file;
	int rc2;
	int rc;

	if (!name) {
		return -EINVAL;
	}

	fs_file_t_init(&file);

	if (cf->cf_maxlines && (cf->cf_lines + 1 >= cf->cf_maxlines)) {
		/*
		 * Compress before config file size exceeds
		 * the max number of lines.
		 */
		return settings_file_save_and_compress(cf, name, value,
						       val_len);
	}

	/*
	 * Open the file to add this one value.
	 */
	rc = fs_open(&file, cf->cf_name, FS_O_CREATE | FS_O_RDWR);
	if (rc == 0) {
		rc = fs_seek(&file, 0, FS_SEEK_END);
		if (rc == 0) {
			entry_ctx.stor_ctx = &file;
			rc = settings_line_write(name, value, val_len, 0,
						  (void *)&entry_ctx);
			if (rc == 0) {
				cf->cf_lines++;
			}
		}

		rc2 = fs_close(&file);
		if (rc == 0) {
			rc = rc2;
		}
	}

	return rc;
}


/*
 * Called to save configuration.
 */
static int settings_file_save(struct settings_store *cs, const char *name,
			      const char *value, size_t val_len)
{
	struct settings_line_dup_check_arg cdca;

	if (val_len > 0 && value == NULL) {
		return -EINVAL;
	}

	/*
	 * Check if we're writing the same value again.
	 */
	cdca.name = name;
	cdca.val = (char *)value;
	cdca.is_dup = 0;
	cdca.val_len = val_len;
	settings_file_load_priv(cs, settings_line_dup_check_cb, &cdca, false);
	if (cdca.is_dup == 1) {
		return 0;
	}
	return settings_file_save_priv(cs, name, (char *)value, val_len);
}

static int read_handler(void *ctx, off_t off, char *buf, size_t *len)
{
	struct line_entry_ctx *entry_ctx = ctx;
	struct fs_file_t *file = entry_ctx->stor_ctx;
	ssize_t r_len;
	int rc;

	/* 0 is reserved for reading the length-field only */
	if (entry_ctx->len != 0) {
		if (off >= entry_ctx->len) {
			*len = 0;
			return 0;
		}

		if ((off + *len) > entry_ctx->len) {
			*len = entry_ctx->len - off;
		}
	}

	rc = fs_seek(file, entry_ctx->seek + off, FS_SEEK_SET);
	if (rc) {
		goto end;
	}

	r_len = fs_read(file, buf, *len);

	if (r_len >= 0) {
		*len = r_len;
		rc = 0;
	} else {
		rc = r_len;
	}
end:
	return rc;
}

static size_t get_len_cb(void *ctx)
{
	struct line_entry_ctx *entry_ctx = ctx;

	return entry_ctx->len;
}

static int write_handler(void *ctx, off_t off, char const *buf, size_t len)
{
	struct line_entry_ctx *entry_ctx = ctx;
	struct fs_file_t *file = entry_ctx->stor_ctx;
	int rc;

	/* append to file only */
	rc = fs_seek(file, 0, FS_SEEK_END);

	if (rc == 0) {
		rc = fs_write(file, buf, len);

		if (rc > 0) {
			rc = 0;
		}
	}

	return rc;
}

void settings_mount_fs_backend(struct settings_file *cf)
{
	settings_line_io_init(read_handler, write_handler, get_len_cb, 1);
}

int settings_backend_init(void)
{
	static struct settings_file config_init_settings_file = {
		.cf_name = CONFIG_SETTINGS_FS_FILE,
		.cf_maxlines = CONFIG_SETTINGS_FS_MAX_LINES
	};
	struct fs_dirent entry;
	int rc;


	rc = settings_file_src(&config_init_settings_file);
	if (rc) {
		k_panic();
	}

	rc = settings_file_dst(&config_init_settings_file);
	if (rc) {
		k_panic();
	}

	settings_mount_fs_backend(&config_init_settings_file);

	/*
	 * Must be called after root FS has been initialized.
	 */
	rc = fs_stat(CONFIG_SETTINGS_FS_DIR, &entry);
	/* If directory doesn't exist, create it */
	if (rc == -ENOENT) {
		rc = fs_mkdir(CONFIG_SETTINGS_FS_DIR);
	}
	return rc;
}

static void *settings_fs_storage_get(struct settings_store *cs)
{
	struct settings_file *cf = (struct settings_file *)cs;

	return (void *)cf->cf_name;
}
