/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <errno.h>
#include <sys/types.h>
#include <zephyr/sys/util.h>

#include <zephyr/bluetooth/hci.h>

#include <zephyr/settings/settings.h>
#include <zephyr/bluetooth/mesh.h>

#include "host/hci_core.h"
#include "mesh.h"
#include "subnet.h"
#include "app_keys.h"
#include "net.h"
#include "cdb.h"
#include "crypto.h"
#include "rpl.h"
#include "transport.h"
#include "heartbeat.h"
#include "access.h"
#include "proxy.h"
#include "pb_gatt_srv.h"
#include "settings.h"
#include "cfg.h"
#include "brg_cfg.h"
#include "solicitation.h"
#include "va.h"

#define LOG_LEVEL CONFIG_BT_MESH_SETTINGS_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_settings);

#ifdef CONFIG_BT_MESH_RPL_STORE_TIMEOUT
#define RPL_STORE_TIMEOUT CONFIG_BT_MESH_RPL_STORE_TIMEOUT
#else
#define RPL_STORE_TIMEOUT (-1)
#endif

#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO
#define SETTINGS_WORKQ_PRIO CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO
#else
#define SETTINGS_WORKQ_PRIO 1
#endif

#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE
#define SETTINGS_WORKQ_STACK_SIZE CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE
#else
#define SETTINGS_WORKQ_STACK_SIZE 0
#endif

static struct k_work_q settings_work_q;
static K_THREAD_STACK_DEFINE(settings_work_stack, SETTINGS_WORKQ_STACK_SIZE);

static struct k_work_delayable pending_store;
static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT);

int bt_mesh_settings_set(settings_read_cb read_cb, void *cb_arg,
			 void *out, size_t read_len)
{
	ssize_t len;

	len = read_cb(cb_arg, out, read_len);
	if (len < 0) {
		LOG_ERR("Failed to read value (err %zd)", len);
		return len;
	}

	LOG_HEXDUMP_DBG(out, len, "val");

	if (len != read_len) {
		LOG_ERR("Unexpected value length (%zd != %zu)", len, read_len);
		return -EINVAL;
	}

	return 0;
}

static int mesh_commit(void)
{
	if (!atomic_test_bit(bt_mesh.flags, BT_MESH_INIT)) {
		return 0;
	}

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) {
		/* The Bluetooth Mesh settings loader calls bt_mesh_start() immediately
		 * after loading the settings. This is not intended to work before
		 * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings
		 * tree to be loaded after @ref bt_enable is completed, so this handler
		 * will be called again later.
		 */
		return 0;
	}

	if (!bt_mesh_subnet_next(NULL)) {
		/* Nothing to do since we're not yet provisioned */
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
		(void)bt_mesh_pb_gatt_srv_disable();
	}

	bt_mesh_net_settings_commit();
	bt_mesh_model_settings_commit();

	atomic_set_bit(bt_mesh.flags, BT_MESH_VALID);

	bt_mesh_start();

	return 0;
}

SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit,
			       NULL);

/* Pending flags that use K_NO_WAIT as the storage timeout */
#define NO_WAIT_PENDING_BITS (BIT(BT_MESH_SETTINGS_NET_PENDING) |           \
			      BIT(BT_MESH_SETTINGS_IV_PENDING)  |           \
			      BIT(BT_MESH_SETTINGS_SEQ_PENDING) |           \
			      BIT(BT_MESH_SETTINGS_CDB_PENDING))

/* Pending flags that use CONFIG_BT_MESH_STORE_TIMEOUT */
#define GENERIC_PENDING_BITS                                                                       \
	(BIT(BT_MESH_SETTINGS_NET_KEYS_PENDING) | BIT(BT_MESH_SETTINGS_APP_KEYS_PENDING) |         \
	 BIT(BT_MESH_SETTINGS_HB_PUB_PENDING) | BIT(BT_MESH_SETTINGS_CFG_PENDING) |                \
	 BIT(BT_MESH_SETTINGS_MOD_PENDING) | BIT(BT_MESH_SETTINGS_VA_PENDING) |                    \
	 BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | BIT(BT_MESH_SETTINGS_COMP_PENDING) |                 \
	 BIT(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING) | BIT(BT_MESH_SETTINGS_BRG_PENDING))

void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag)
{
	uint32_t timeout_ms, remaining_ms;

	atomic_set_bit(pending_flags, flag);

	if (atomic_get(pending_flags) & NO_WAIT_PENDING_BITS) {
		timeout_ms = 0;
	} else if (IS_ENABLED(CONFIG_BT_MESH_RPL_STORAGE_MODE_SETTINGS) && RPL_STORE_TIMEOUT >= 0 &&
		   (atomic_test_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING) ||
		     atomic_test_bit(pending_flags, BT_MESH_SETTINGS_SRPL_PENDING)) &&
		   !(atomic_get(pending_flags) & GENERIC_PENDING_BITS)) {
		timeout_ms = RPL_STORE_TIMEOUT * MSEC_PER_SEC;
	} else {
		timeout_ms = CONFIG_BT_MESH_STORE_TIMEOUT * MSEC_PER_SEC;
	}

	remaining_ms = k_ticks_to_ms_floor32(k_work_delayable_remaining_get(&pending_store));
	LOG_DBG("Waiting %u ms vs rem %u ms", timeout_ms, remaining_ms);

	/* If the new deadline is sooner, override any existing
	 * deadline; otherwise schedule without changing any existing
	 * deadline.
	 */
	if (timeout_ms < remaining_ms) {
		if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
			k_work_reschedule_for_queue(&settings_work_q, &pending_store,
						    K_MSEC(timeout_ms));
		} else {
			k_work_reschedule(&pending_store, K_MSEC(timeout_ms));
		}
	} else {
		if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
			k_work_schedule_for_queue(&settings_work_q, &pending_store,
						  K_MSEC(timeout_ms));
		} else {
			k_work_schedule(&pending_store, K_MSEC(timeout_ms));
		}
	}
}

void bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag)
{
	atomic_clear_bit(pending_flags, flag);
}

static void store_pending(struct k_work *work)
{
	LOG_DBG("");

	static const struct {
		void (*handler)(void);
	} handlers[BT_MESH_SETTINGS_FLAG_COUNT] = {
		[BT_MESH_SETTINGS_RPL_PENDING]      = { bt_mesh_rpl_pending_store_all_nodes },
		[BT_MESH_SETTINGS_NET_KEYS_PENDING] = { bt_mesh_subnet_pending_store },
		[BT_MESH_SETTINGS_APP_KEYS_PENDING] = { bt_mesh_app_key_pending_store },
		[BT_MESH_SETTINGS_NET_PENDING]	    = { bt_mesh_net_pending_net_store },
		[BT_MESH_SETTINGS_IV_PENDING]	    = { bt_mesh_net_pending_iv_store },
		[BT_MESH_SETTINGS_SEQ_PENDING]	    = { bt_mesh_net_pending_seq_store },
		[BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING] = {
			bt_mesh_net_pending_dev_key_cand_store },
		[BT_MESH_SETTINGS_HB_PUB_PENDING]   = { bt_mesh_hb_pub_pending_store },
		[BT_MESH_SETTINGS_CFG_PENDING]	    = { bt_mesh_cfg_pending_store },
		[BT_MESH_SETTINGS_COMP_PENDING]	    = { bt_mesh_comp_data_pending_clear },
		[BT_MESH_SETTINGS_MOD_PENDING]	    = { bt_mesh_model_pending_store },
		[BT_MESH_SETTINGS_VA_PENDING]	    = { bt_mesh_va_pending_store },
		[BT_MESH_SETTINGS_CDB_PENDING]	    = {
			IS_ENABLED(CONFIG_BT_MESH_CDB) ?
				bt_mesh_cdb_pending_store : NULL },
		[BT_MESH_SETTINGS_SRPL_PENDING]     = {
			IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) ?
				bt_mesh_srpl_pending_store : NULL },
		[BT_MESH_SETTINGS_SSEQ_PENDING]     = {
			IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) ?
				bt_mesh_sseq_pending_store : NULL },
		[BT_MESH_SETTINGS_BRG_PENDING]      = {
			IS_ENABLED(CONFIG_BT_MESH_BRG_CFG_SRV) ?
				bt_mesh_brg_cfg_pending_store : NULL },
	};

	for (int i = 0; i < ARRAY_SIZE(handlers); i++) {
		if (!handlers[i].handler) {
			continue;
		}

		if (atomic_test_and_clear_bit(pending_flags, i)) {
			handlers[i].handler();
		}
	}
}

void bt_mesh_settings_init(void)
{
	if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
		k_work_queue_start(&settings_work_q, settings_work_stack,
				   K_THREAD_STACK_SIZEOF(settings_work_stack),
				   K_PRIO_COOP(SETTINGS_WORKQ_PRIO), NULL);
		k_thread_name_set(&settings_work_q.thread, "BT Mesh settings workq");
	}

	k_work_init_delayable(&pending_store, store_pending);
}

void bt_mesh_settings_store_pending(void)
{
	(void)k_work_cancel_delayable(&pending_store);

	store_pending(&pending_store.work);
}
