/*
 * Copyright (c) 2019 Tobias Svehagen
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <bluetooth/mesh.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_PROV)
#define LOG_MODULE_NAME bt_mesh_node
#include "common/log.h"

#include "mesh.h"
#include "net.h"
#include "access.h"
#include "settings.h"

/*
 * Check if an address range from addr_start for addr_start + num_elem - 1 is
 * free for use. When a conflict is found, next will be set to the next address
 * available after the conflicting range and -EAGAIN will be returned.
 */
static int addr_is_free(u16_t addr_start, u8_t num_elem, u16_t *next)
{
	const struct bt_mesh_comp *comp = bt_mesh_comp_get();
	u16_t addr_end = addr_start + num_elem - 1;
	u16_t other_start, other_end;
	int i;

	if (comp == NULL) {
		return -EINVAL;
	}

	if (!BT_MESH_ADDR_IS_UNICAST(addr_start) ||
	    !BT_MESH_ADDR_IS_UNICAST(addr_end) ||
	    num_elem == 0 || next == NULL) {
		return -EINVAL;
	}

	other_start = bt_mesh_primary_addr();
	other_end = other_start + comp->elem_count - 1;

	/* Compare with local element addresses */
	if (!(addr_end < other_start || addr_start > other_end)) {
		*next = other_end + 1;
		return -EAGAIN;
	}

	for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) {
		struct bt_mesh_node *node = &bt_mesh.nodes[i];

		if (node->net_idx == BT_MESH_KEY_UNUSED) {
			continue;
		}

		other_start = node->addr;
		other_end = other_start + node->num_elem - 1;

		if (!(addr_end < other_start || addr_start > other_end)) {
			*next = other_end + 1;
			return -EAGAIN;
		}
	}

	return 0;
}

/*
 * Find the lowest possible starting address that can fit num_elem elements. If
 * a free address range cannot be found, BT_MESH_ADDR_UNASSIGNED will be
 * returned. Otherwise the first address in the range is returned.
 *
 * NOTE: This is quite an ineffective algorithm as it might need to look
 *       through the array of nodes N+2 times. A more effective algorithm
 *       could be used if the nodes were stored in a sorted list.
 */
static u16_t find_lowest_free_addr(u8_t num_elem)
{
	u16_t addr = 1, next;
	int err, i;

	/*
	 * It takes a maximum of node count + 2 to find a free address if there
	 * is any. +1 for our own address and +1 for making sure that the
	 * address range is valid.
	 */
	for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes) + 2; ++i) {
		err = addr_is_free(addr, num_elem, &next);
		if (err == 0) {
			break;
		} else if (err != -EAGAIN) {
			addr = BT_MESH_ADDR_UNASSIGNED;
			break;
		}

		addr = next;
	}

	return addr;
}

struct bt_mesh_node *bt_mesh_node_find(u16_t addr)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) {
		struct bt_mesh_node *node = &bt_mesh.nodes[i];

		if (addr >= node->addr &&
		    addr <= node->addr + node->num_elem - 1) {
			return node;
		}
	}

	return NULL;
}

struct bt_mesh_node *bt_mesh_node_alloc(u16_t addr, u8_t num_elem,
					u16_t net_idx)
{
	int i;

	BT_DBG("");

	if (addr == BT_MESH_ADDR_UNASSIGNED) {
		addr = find_lowest_free_addr(num_elem);
		if (addr == BT_MESH_ADDR_UNASSIGNED) {
			return NULL;
		}
	} else if (!addr_is_free(addr, num_elem, NULL)) {
		return NULL;
	}

	for (i = 0; i < ARRAY_SIZE(bt_mesh.nodes); i++) {
		struct bt_mesh_node *node = &bt_mesh.nodes[i];

		if (node->addr == BT_MESH_ADDR_UNASSIGNED) {
			node->addr = addr;
			node->num_elem = num_elem;
			node->net_idx = net_idx;
			return node;
		}
	}

	return NULL;
}

void bt_mesh_node_del(struct bt_mesh_node *node, bool store)
{
	BT_DBG("Node addr 0x%04x store %u", node->addr, store);

	if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
		bt_mesh_clear_node(node);
	}

	node->addr = BT_MESH_ADDR_UNASSIGNED;
	(void)memset(node->dev_key, 0, sizeof(node->dev_key));
}
