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

#include <errno.h>
#include <stdbool.h>
#include <zephyr/fs/fcb.h>
#include <string.h>

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

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL);

#if DT_HAS_CHOSEN(zephyr_settings_partition)
#define SETTINGS_PARTITION DT_FIXED_PARTITION_ID(DT_CHOSEN(zephyr_settings_partition))
#else
#define SETTINGS_PARTITION FIXED_PARTITION_ID(storage_partition)
#endif

#define SETTINGS_FCB_VERS		1

int settings_backend_init(void);
void settings_mount_fcb_backend(struct settings_fcb *cf);
static void *settings_fcb_storage_get(struct settings_store *cs);

static int settings_fcb_load(struct settings_store *cs,
			     const struct settings_load_arg *arg);
static int settings_fcb_save(struct settings_store *cs, const char *name,
			     const char *value, size_t val_len);
static void *settings_fcb_storage_get(struct settings_store *cs);

static const struct settings_store_itf settings_fcb_itf = {
	.csi_load = settings_fcb_load,
	.csi_save = settings_fcb_save,
	.csi_storage_get = settings_fcb_storage_get
};

/**
 * @brief Get the flash area id of the storage partition
 *
 * The implementation of this function provided is weak to let user defines its own function.
 * This may prove useful for devices using bank swap, in that case the flash area id changes based
 * on the bank swap state.
 * See #47732
 *
 * @return Flash area id
 */
__weak int settings_fcb_get_flash_area(void)
{
	return SETTINGS_PARTITION;
}

int settings_fcb_src(struct settings_fcb *cf)
{
	int rc;

	cf->cf_fcb.f_version = SETTINGS_FCB_VERS;
	cf->cf_fcb.f_scratch_cnt = 1;

	while (1) {
		rc = fcb_init(settings_fcb_get_flash_area(), &cf->cf_fcb);
		if (rc) {
			return -EINVAL;
		}

		/*
		 * Check if system was reset in middle of emptying a sector.
		 * This situation is recognized by checking if the scratch block
		 * is missing.
		 */
		if (fcb_free_sector_cnt(&cf->cf_fcb) < 1) {

			rc = flash_area_erase(cf->cf_fcb.fap,
					cf->cf_fcb.f_active.fe_sector->fs_off,
					cf->cf_fcb.f_active.fe_sector->fs_size);

			if (rc) {
				return -EIO;
			}
		} else {
			break;
		}
	}

	cf->cf_store.cs_itf = &settings_fcb_itf;
	settings_src_register(&cf->cf_store);

	return 0;
}

int settings_fcb_dst(struct settings_fcb *cf)
{
	cf->cf_store.cs_itf = &settings_fcb_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 cf        FCB handler
 * @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_fcb_check_duplicate(struct settings_fcb *cf,
					const struct fcb_entry_ctx *entry_ctx,
					const char * const name)
{
	struct fcb_entry_ctx entry2_ctx = *entry_ctx;

	while (fcb_getnext(&cf->cf_fcb, &entry2_ctx.loc) == 0) {
		char name2[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
		size_t name2_len;

		if (settings_line_name_read(name2, sizeof(name2), &name2_len,
					    &entry2_ctx)) {
			LOG_ERR("failed to load line");
			continue;
		}
		name2[name2_len] = '\0';
		if (!strcmp(name, name2)) {
			return true;
		}
	}
	return false;
}

static int read_entry_len(const struct fcb_entry_ctx *entry_ctx, off_t off)
{
	if (off >= entry_ctx->loc.fe_data_len) {
		return 0;
	}
	return entry_ctx->loc.fe_data_len - off;
}

static int settings_fcb_load_priv(struct settings_store *cs,
				  line_load_cb cb,
				  void *cb_arg,
				  bool filter_duplicates)
{
	struct settings_fcb *cf = CONTAINER_OF(cs, struct settings_fcb, cf_store);
	struct fcb_entry_ctx entry_ctx = {
		{.fe_sector = NULL, .fe_elem_off = 0},
		.fap = cf->cf_fcb.fap
	};
	int rc;

	while ((rc = fcb_getnext(&cf->cf_fcb, &entry_ctx.loc)) == 0) {
		char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
		size_t name_len;
		int rc;
		bool pass_entry = true;

		rc = settings_line_name_read(name, sizeof(name), &name_len,
					     (void *)&entry_ctx);
		if (rc) {
			LOG_ERR("Failed to load line name: %d", rc);
			continue;
		}
		name[name_len] = '\0';

		if (filter_duplicates &&
		    (!read_entry_len(&entry_ctx, name_len+1) ||
		     settings_fcb_check_duplicate(cf, &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, &entry_ctx, name_len + 1, cb_arg);
		}
	}
	if (rc == -ENOTSUP) {
		rc = 0;
	}
	return 0;
}

static int settings_fcb_load(struct settings_store *cs,
			     const struct settings_load_arg *arg)
{
	return settings_fcb_load_priv(
		cs,
		settings_line_load_cb,
		(void *)arg,
		true);
}

static int read_handler(void *ctx, off_t off, char *buf, size_t *len)
{
	struct fcb_entry_ctx *entry_ctx = ctx;

	if (off >= entry_ctx->loc.fe_data_len) {
		*len = 0;
		return 0;
	}

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

	return flash_area_read(entry_ctx->fap,
			       FCB_ENTRY_FA_DATA_OFF(entry_ctx->loc) + off, buf,
			       *len);
}

static void settings_fcb_compress(struct settings_fcb *cf)
{
	int rc;
	struct fcb_entry_ctx loc1;
	struct fcb_entry_ctx loc2;
	char name1[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN];
	char name2[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN];
	int copy;
	uint8_t rbs;

	rc = fcb_append_to_scratch(&cf->cf_fcb);
	if (rc) {
		return; /* XXX */
	}

	rbs = flash_area_align(cf->cf_fcb.fap);

	loc1.fap = cf->cf_fcb.fap;

	loc1.loc.fe_sector = NULL;
	loc1.loc.fe_elem_off = 0U;

	while (fcb_getnext(&cf->cf_fcb, &loc1.loc) == 0) {
		if (loc1.loc.fe_sector != cf->cf_fcb.f_oldest) {
			break;
		}

		size_t val1_off;

		rc = settings_line_name_read(name1, sizeof(name1), &val1_off,
					     &loc1);
		if (rc) {
			continue;
		}

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

		loc2 = loc1;
		copy = 1;

		while (fcb_getnext(&cf->cf_fcb, &loc2.loc) == 0) {
			size_t val2_off;

			rc = settings_line_name_read(name2, sizeof(name2),
						     &val2_off, &loc2);
			if (rc) {
				continue;
			}

			if ((val1_off == val2_off) &&
			    !memcmp(name1, name2, val1_off)) {
				copy = 0;
				break;
			}
		}
		if (!copy) {
			continue;
		}

		/*
		 * Can't find one. Must copy.
		 */
		rc = fcb_append(&cf->cf_fcb, loc1.loc.fe_data_len, &loc2.loc);
		if (rc) {
			continue;
		}

		rc = settings_line_entry_copy(&loc2, 0, &loc1, 0,
					      loc1.loc.fe_data_len);
		if (rc) {
			continue;
		}
		rc = fcb_append_finish(&cf->cf_fcb, &loc2.loc);

		if (rc != 0) {
			LOG_ERR("Failed to finish fcb_append (%d)", rc);
		}
	}
	rc = fcb_rotate(&cf->cf_fcb);

	if (rc != 0) {
		LOG_ERR("Failed to fcb rotate (%d)", rc);
	}
}

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

	return entry_ctx->loc.fe_data_len;
}

static int write_handler(void *ctx, off_t off, char const *buf, size_t len)
{
	struct fcb_entry_ctx *entry_ctx = ctx;

	return flash_area_write(entry_ctx->fap,
				FCB_ENTRY_FA_DATA_OFF(entry_ctx->loc) + off,
				buf, len);
}

/* ::csi_save implementation */
static int settings_fcb_save_priv(struct settings_store *cs, const char *name,
				  const char *value, size_t val_len)
{
	struct settings_fcb *cf = CONTAINER_OF(cs, struct settings_fcb, cf_store);
	struct fcb_entry_ctx loc;
	int len;
	int rc = -EINVAL;
	int i;
	uint8_t wbs;

	if (!name) {
		return -EINVAL;
	}

	wbs = cf->cf_fcb.f_align;
	len = settings_line_len_calc(name, val_len);

	for (i = 0; i < cf->cf_fcb.f_sector_cnt; i++) {
		rc = fcb_append(&cf->cf_fcb, len, &loc.loc);
		if (rc != -ENOSPC) {
			break;
		}

		/* FCB can compress up to cf->cf_fcb.f_sector_cnt - 1 times. */
		if (i < (cf->cf_fcb.f_sector_cnt - 1)) {
			settings_fcb_compress(cf);
		}
	}
	if (rc) {
		return -EINVAL;
	}

	loc.fap = cf->cf_fcb.fap;

	rc = settings_line_write(name, value, val_len, 0, (void *)&loc);

	if (rc != -EIO) {
		i = fcb_append_finish(&cf->cf_fcb, &loc.loc);
		if (!rc) {
			rc = i;
		}
	}
	return rc;
}

static int settings_fcb_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_fcb_load_priv(cs, settings_line_dup_check_cb, &cdca, false);
	if (cdca.is_dup == 1) {
		return 0;
	}
	return settings_fcb_save_priv(cs, name, value, val_len);
}

void settings_mount_fcb_backend(struct settings_fcb *cf)
{
	uint8_t rbs;

	rbs = cf->cf_fcb.f_align;

	settings_line_io_init(read_handler, write_handler, get_len_cb, rbs);
}

int settings_backend_init(void)
{
	static struct flash_sector
		settings_fcb_area[CONFIG_SETTINGS_FCB_NUM_AREAS + 1];
	static struct settings_fcb config_init_settings_fcb = {
		.cf_fcb.f_magic = CONFIG_SETTINGS_FCB_MAGIC,
		.cf_fcb.f_sectors = settings_fcb_area,
	};
	uint32_t cnt = sizeof(settings_fcb_area) /
		    sizeof(settings_fcb_area[0]);
	int rc;
	const struct flash_area *fap;

	rc = flash_area_get_sectors(settings_fcb_get_flash_area(), &cnt,
				    settings_fcb_area);
	if (rc == -ENODEV) {
		return rc;
	} else if (rc != 0 && rc != -ENOMEM) {
		k_panic();
	}

	config_init_settings_fcb.cf_fcb.f_sector_cnt = cnt;

	rc = settings_fcb_src(&config_init_settings_fcb);

	if (rc != 0) {
		rc = flash_area_open(settings_fcb_get_flash_area(), &fap);

		if (rc == 0) {
			rc = flash_area_erase(fap, 0, fap->fa_size);
			flash_area_close(fap);
		}

		if (rc != 0) {
			k_panic();
		} else {
			rc = settings_fcb_src(&config_init_settings_fcb);
		}
	}

	if (rc != 0) {
		k_panic();
	}

	rc = settings_fcb_dst(&config_init_settings_fcb);

	if (rc != 0) {
		k_panic();
	}

	settings_mount_fcb_backend(&config_init_settings_fcb);

	return rc;
}

static void *settings_fcb_storage_get(struct settings_store *cs)
{
	struct settings_fcb *cf = CONTAINER_OF(cs, struct settings_fcb, cf_store);

	return &cf->cf_fcb;
}
