/*
 * Copyright (c) 2017 Intel Corporation
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <stdlib.h>
#include <bluetooth/mesh.h>
#include <bluetooth/conn.h>
#include "mesh.h"
#include "net.h"
#include "app_keys.h"
#include "rpl.h"
#include "settings.h"
#include "crypto.h"
#include "adv.h"
#include "proxy.h"
#include "friend.h"
#include "foundation.h"
#include "access.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_KEYS)
#define LOG_MODULE_NAME bt_mesh_app_keys
#include "common/log.h"

/* Tracking of what storage changes are pending for App Keys. We track this in
 * a separate array here instead of within the respective bt_mesh_app_key
 * struct itself, since once a key gets deleted its struct becomes invalid
 * and may be reused for other keys.
 */
struct app_key_update {
	uint16_t key_idx:12,    /* AppKey Index */
		 valid:1,       /* 1 if this entry is valid, 0 if not */
		 clear:1;       /* 1 if key needs clearing, 0 if storing */
};

/* AppKey information for persistent storage. */
struct app_key_val {
	uint16_t net_idx;
	bool     updated;
	uint8_t  val[2][16];
} __packed;

/** Mesh Application Key. */
struct app_key {
	uint16_t net_idx;
	uint16_t app_idx;
	bool updated;
	struct bt_mesh_app_cred {
		uint8_t id;
		uint8_t val[16];
	} keys[2];
};

static struct app_key_update app_key_updates[CONFIG_BT_MESH_APP_KEY_COUNT];

static struct app_key apps[CONFIG_BT_MESH_APP_KEY_COUNT] = {
	[0 ... (CONFIG_BT_MESH_APP_KEY_COUNT - 1)] = {
		.app_idx = BT_MESH_KEY_UNUSED,
		.net_idx = BT_MESH_KEY_UNUSED,
	}
};

static struct app_key *app_get(uint16_t app_idx)
{
	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		if (apps[i].app_idx == app_idx) {
			return &apps[i];
		}
	}

	return NULL;
}

static void clear_app_key(uint16_t app_idx)
{
	char path[20];
	int err;

	snprintk(path, sizeof(path), "bt/mesh/AppKey/%x", app_idx);
	err = settings_delete(path);
	if (err) {
		BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx);
	} else {
		BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx);
	}
}

static void store_app_key(uint16_t app_idx)
{
	const struct app_key *app;
	struct app_key_val key;
	char path[20];
	int err;

	snprintk(path, sizeof(path), "bt/mesh/AppKey/%x", app_idx);

	app = app_get(app_idx);
	if (!app) {
		BT_WARN("ApKeyIndex 0x%03x not found", app_idx);
		return;
	}

	key.net_idx = app->net_idx,
	key.updated = app->updated,

	memcpy(key.val[0], app->keys[0].val, 16);
	memcpy(key.val[1], app->keys[1].val, 16);

	err = settings_save_one(path, &key, sizeof(key));
	if (err) {
		BT_ERR("Failed to store AppKey %s value", log_strdup(path));
	} else {
		BT_DBG("Stored AppKey %s value", log_strdup(path));
	}
}

static struct app_key_update *app_key_update_find(uint16_t key_idx,
					struct app_key_update **free_slot)
{
	struct app_key_update *match;
	int i;

	match = NULL;
	*free_slot = NULL;

	for (i = 0; i < ARRAY_SIZE(app_key_updates); i++) {
		struct app_key_update *update = &app_key_updates[i];

		if (!update->valid) {
			*free_slot = update;
			continue;
		}

		if (update->key_idx == key_idx) {
			match = update;
		}
	}

	return match;
}

static void update_app_key_settings(uint16_t app_idx, bool store)
{
	struct app_key_update *update, *free_slot;
	uint8_t clear = store ? 0U : 1U;

	BT_DBG("AppKeyIndex 0x%03x", app_idx);

	update = app_key_update_find(app_idx, &free_slot);
	if (update) {
		update->clear = clear;
		bt_mesh_settings_store_schedule(
					BT_MESH_SETTINGS_APP_KEYS_PENDING);
		return;
	}

	if (!free_slot) {
		if (store) {
			store_app_key(app_idx);
		} else {
			clear_app_key(app_idx);
		}
		return;
	}

	free_slot->valid = 1U;
	free_slot->key_idx = app_idx;
	free_slot->clear = clear;

	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_APP_KEYS_PENDING);
}

static void app_key_evt(struct app_key *app, enum bt_mesh_key_evt evt)
{
	STRUCT_SECTION_FOREACH(bt_mesh_app_key_cb, cb) {
		cb->evt_handler(app->app_idx, app->net_idx, evt);
	}
}

static struct app_key *app_key_alloc(uint16_t app_idx)
{
	struct app_key *app = NULL;

	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		/* Check for already existing app_key */
		if (apps[i].app_idx == app_idx) {
			return &apps[i];
		}

		if (!app && apps[i].app_idx == BT_MESH_KEY_UNUSED) {
			app = &apps[i];
		}
	}

	return app;
}

static void app_key_del(struct app_key *app)
{
	BT_DBG("AppIdx 0x%03x", app->app_idx);

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		update_app_key_settings(app->app_idx, false);
	}

	app_key_evt(app, BT_MESH_KEY_DELETED);

	app->net_idx = BT_MESH_KEY_UNUSED;
	app->app_idx = BT_MESH_KEY_UNUSED;
	(void)memset(app->keys, 0, sizeof(app->keys));
}

static void app_key_revoke(struct app_key *app)
{
	if (!app->updated) {
		return;
	}

	memcpy(&app->keys[0], &app->keys[1], sizeof(app->keys[0]));
	memset(&app->keys[1], 0, sizeof(app->keys[1]));
	app->updated = false;

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		update_app_key_settings(app->app_idx, true);
	}

	app_key_evt(app, BT_MESH_KEY_REVOKED);
}

uint8_t bt_mesh_app_key_add(uint16_t app_idx, uint16_t net_idx,
			const uint8_t key[16])
{
	struct app_key *app;

	BT_DBG("net_idx 0x%04x app_idx %04x val %s", net_idx, app_idx,
	       bt_hex(key, 16));

	if (!bt_mesh_subnet_get(net_idx)) {
		return STATUS_INVALID_NETKEY;
	}

	app = app_key_alloc(app_idx);
	if (!app) {
		return STATUS_INSUFF_RESOURCES;
	}

	if (app->app_idx == app_idx) {
		if (app->net_idx != net_idx) {
			return STATUS_INVALID_NETKEY;
		}

		if (memcmp(key, app->keys[0].val, 16)) {
			return STATUS_IDX_ALREADY_STORED;
		}

		return STATUS_SUCCESS;
	}

	if (bt_mesh_app_id(key, &app->keys[0].id)) {
		return STATUS_CANNOT_SET;
	}

	BT_DBG("AppIdx 0x%04x AID 0x%02x", app_idx, app->keys[0].id);

	app->net_idx = net_idx;
	app->app_idx = app_idx;
	app->updated = false;
	memcpy(app->keys[0].val, key, 16);

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		BT_DBG("Storing AppKey persistently");
		update_app_key_settings(app->app_idx, true);
	}

	app_key_evt(app, BT_MESH_KEY_ADDED);

	return STATUS_SUCCESS;
}

uint8_t bt_mesh_app_key_update(uint16_t app_idx, uint16_t net_idx,
			       const uint8_t key[16])
{
	struct app_key *app;
	struct bt_mesh_subnet *sub;

	BT_DBG("net_idx 0x%04x app_idx %04x val %s", net_idx, app_idx,
	       bt_hex(key, 16));

	app = app_get(app_idx);
	if (!app) {
		return STATUS_INVALID_APPKEY;
	}

	if (net_idx != BT_MESH_KEY_UNUSED && app->net_idx != net_idx) {
		return STATUS_INVALID_BINDING;
	}

	sub = bt_mesh_subnet_get(app->net_idx);
	if (!sub) {
		return STATUS_INVALID_NETKEY;
	}

	/* The AppKey Update message shall generate an error when node
	 * is in normal operation, Phase 2, or Phase 3 or in Phase 1
	 * when the AppKey Update message on a valid AppKeyIndex when
	 * the AppKey value is different.
	 */
	if (sub->kr_phase != BT_MESH_KR_PHASE_1) {
		return STATUS_CANNOT_UPDATE;
	}

	if (app->updated) {
		if (memcmp(app->keys[1].val, key, 16)) {
			return STATUS_IDX_ALREADY_STORED;
		}

		return STATUS_SUCCESS;
	}

	if (bt_mesh_app_id(key, &app->keys[1].id)) {
		return STATUS_CANNOT_UPDATE;
	}

	BT_DBG("app_idx 0x%04x AID 0x%02x", app_idx, app->keys[1].id);

	app->updated = true;
	memcpy(app->keys[1].val, key, 16);

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		BT_DBG("Storing AppKey persistently");
		update_app_key_settings(app->app_idx, true);
	}

	app_key_evt(app, BT_MESH_KEY_UPDATED);

	return STATUS_SUCCESS;
}

uint8_t bt_mesh_app_key_del(uint16_t app_idx, uint16_t net_idx)
{
	struct app_key *app;

	BT_DBG("AppIdx 0x%03x", app_idx);

	if (net_idx != BT_MESH_KEY_UNUSED && !bt_mesh_subnet_get(net_idx)) {
		return STATUS_INVALID_NETKEY;
	}

	app = app_get(app_idx);
	if (!app) {
		/* This could be a retry of a previous attempt that had its
		 * response lost, so pretend that it was a success.
		 */
		return STATUS_SUCCESS;
	}

	if (net_idx != BT_MESH_KEY_UNUSED && net_idx != app->net_idx) {
		return STATUS_INVALID_BINDING;
	}

	app_key_del(app);

	return STATUS_SUCCESS;
}

int bt_mesh_app_key_set(uint16_t app_idx, uint16_t net_idx,
		    const uint8_t old_key[16], const uint8_t new_key[16])
{
	struct app_key *app;

	app = app_key_alloc(app_idx);
	if (!app) {
		return -ENOMEM;
	}

	if (app->app_idx == app_idx) {
		return 0;
	}

	BT_DBG("AppIdx 0x%04x AID 0x%02x", app_idx, app->keys[0].id);

	memcpy(app->keys[0].val, old_key, 16);
	if (bt_mesh_app_id(old_key, &app->keys[0].id)) {
		return -EIO;
	}

	if (new_key) {
		memcpy(app->keys[1].val, new_key, 16);
		if (bt_mesh_app_id(new_key, &app->keys[1].id)) {
			return -EIO;
		}
	}

	app->net_idx = net_idx;
	app->app_idx = app_idx;
	app->updated = !!new_key;

	return 0;
}

bool bt_mesh_app_key_exists(uint16_t app_idx)
{
	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		if (apps[i].app_idx == app_idx) {
			return true;
		}
	}

	return false;
}

ssize_t bt_mesh_app_keys_get(uint16_t net_idx, uint16_t app_idxs[], size_t max,
			     off_t skip)
{
	size_t count = 0;

	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		struct app_key *app = &apps[i];

		if (app->app_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		if (net_idx != BT_MESH_KEY_ANY && app->net_idx != net_idx) {
			continue;
		}

		if (skip) {
			skip--;
			continue;
		}

		if (count >= max) {
			return -ENOMEM;
		}

		app_idxs[count++] = app->app_idx;
	}

	return count;
}

int bt_mesh_keys_resolve(struct bt_mesh_msg_ctx *ctx,
			 struct bt_mesh_subnet **sub,
			 const uint8_t **app_key, uint8_t *aid)
{
	struct app_key *app = NULL;

	if (BT_MESH_IS_DEV_KEY(ctx->app_idx)) {
		/* With device keys, the application has to decide which subnet
		 * to send on.
		 */
		*sub = bt_mesh_subnet_get(ctx->net_idx);
		if (!*sub) {
			BT_WARN("Unknown NetKey 0x%03x", ctx->net_idx);
			return -EINVAL;
		}

		if (ctx->app_idx == BT_MESH_KEY_DEV_REMOTE &&
		    !bt_mesh_has_addr(ctx->addr)) {
			struct bt_mesh_cdb_node *node;

			if (!IS_ENABLED(CONFIG_BT_MESH_CDB)) {
				BT_WARN("No DevKey for 0x%04x", ctx->addr);
				return -EINVAL;
			}

			node = bt_mesh_cdb_node_get(ctx->addr);
			if (!node) {
				BT_WARN("No DevKey for 0x%04x", ctx->addr);
				return -EINVAL;
			}

			*app_key = node->dev_key;
		} else {
			*app_key = bt_mesh.dev_key;
		}

		*aid = 0;
		return 0;
	}

	app = app_get(ctx->app_idx);
	if (!app) {
		BT_WARN("Unknown AppKey 0x%03x", ctx->app_idx);
		return -EINVAL;
	}

	*sub = bt_mesh_subnet_get(app->net_idx);
	if (!*sub) {
		BT_WARN("Unknown NetKey 0x%03x", app->net_idx);
		return -EINVAL;
	}

	if ((*sub)->kr_phase == BT_MESH_KR_PHASE_2 && app->updated) {
		*aid = app->keys[1].id;
		*app_key = app->keys[1].val;
	} else {
		*aid = app->keys[0].id;
		*app_key = app->keys[0].val;
	}

	return 0;
}

uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid,
			      struct bt_mesh_net_rx *rx,
			      int (*cb)(struct bt_mesh_net_rx *rx,
					const uint8_t key[16], void *cb_data),
			      void *cb_data)
{
	int err, i;

	if (dev_key) {
		/* Attempt remote dev key first, as that is only available for
		 * provisioner devices, which normally don't interact with nodes
		 * that know their local dev key.
		 */
		if (IS_ENABLED(CONFIG_BT_MESH_CDB) &&
		    rx->net_if != BT_MESH_NET_IF_LOCAL) {
			struct bt_mesh_cdb_node *node;

			node = bt_mesh_cdb_node_get(rx->ctx.addr);
			if (node && !cb(rx, node->dev_key, cb_data)) {
				return BT_MESH_KEY_DEV_REMOTE;
			}
		}

		/** Bluetooth Mesh Specification v1.0.1, section 3.4.3:
		 *  The Device key is only valid for unicast addresses.
		 */
		if (BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) {
			err = cb(rx, bt_mesh.dev_key, cb_data);
			if (!err) {
				return BT_MESH_KEY_DEV_LOCAL;
			}
		}

		return BT_MESH_KEY_UNUSED;
	}

	for (i = 0; i < ARRAY_SIZE(apps); i++) {
		const struct app_key *app = &apps[i];
		const struct bt_mesh_app_cred *cred;

		if (app->app_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		if (app->net_idx != rx->sub->net_idx) {
			continue;
		}

		if (rx->new_key && app->updated) {
			cred = &app->keys[1];
		} else {
			cred = &app->keys[0];
		}

		if (cred->id != aid) {
			continue;
		}

		err = cb(rx, cred->val, cb_data);
		if (err) {
			continue;
		}

		return app->app_idx;
	}

	return BT_MESH_KEY_UNUSED;
}

static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
{
	if (evt == BT_MESH_KEY_UPDATED || evt == BT_MESH_KEY_ADDED) {
		return;
	}

	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		struct app_key *app = &apps[i];

		if (app->app_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		if (app->net_idx != sub->net_idx) {
			continue;
		}

		if (evt == BT_MESH_KEY_DELETED) {
			app_key_del(app);
		} else if (evt == BT_MESH_KEY_REVOKED) {
			app_key_revoke(app);
		} else if (evt == BT_MESH_KEY_SWAPPED && app->updated) {
			app_key_evt(app, BT_MESH_KEY_SWAPPED);
		}
	}
}

BT_MESH_SUBNET_CB_DEFINE(app_keys) = {
	.evt_handler = subnet_evt,
};

void bt_mesh_app_keys_reset(void)
{
	for (int i = 0; i < ARRAY_SIZE(apps); i++) {
		struct app_key *app = &apps[i];

		if (app->app_idx != BT_MESH_KEY_UNUSED) {
			app_key_del(app);
		}
	}
}

static int app_key_set(const char *name, size_t len_rd,
		       settings_read_cb read_cb, void *cb_arg)
{
	struct app_key_val key;
	uint16_t app_idx;
	int err;

	if (!name) {
		BT_ERR("Insufficient number of arguments");
		return -ENOENT;
	}

	app_idx = strtol(name, NULL, 16);

	if (!len_rd) {
		return 0;
	}

	err = bt_mesh_settings_set(read_cb, cb_arg, &key, sizeof(key));
	if (err < 0) {
		return -EINVAL;
	}

	err = bt_mesh_app_key_set(app_idx, key.net_idx, key.val[0],
			      key.updated ? key.val[1] : NULL);
	if (err) {
		BT_ERR("Failed to set \'app-key\'");
		return err;
	}

	BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx);

	return 0;
}

BT_MESH_SETTINGS_DEFINE(app, "AppKey", app_key_set);

void bt_mesh_app_key_pending_store(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(app_key_updates); i++) {
		struct app_key_update *update = &app_key_updates[i];

		if (!update->valid) {
			continue;
		}

		if (update->clear) {
			clear_app_key(update->key_idx);
		} else {
			store_app_key(update->key_idx);
		}

		update->valid = 0U;
	}
}
