/*
 * Copyright (c) 2017 Intel Corporation
 * Copyright (c) 2020 Lingao Meng
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/zephyr.h>
#include <errno.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/mesh.h>
#include <zephyr/bluetooth/uuid.h>

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

#include "host/ecc.h"
#include "host/testing.h"

#include "crypto.h"
#include "mesh.h"
#include "net.h"
#include "access.h"
#include "foundation.h"
#include "prov.h"

struct bt_mesh_prov_link bt_mesh_prov_link;
const struct bt_mesh_prov *bt_mesh_prov;

/* Verify specification defined length: */
BUILD_ASSERT(sizeof(bt_mesh_prov_link.conf_inputs) == 145,
	     "Confirmation inputs shall be 145 bytes");

static void pub_key_ready(const uint8_t *pkey)
{
	if (!pkey) {
		BT_WARN("Public key not available");
		return;
	}

	BT_DBG("Local public key ready");
}

int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[BT_PUB_KEY_LEN]))
{
	int err;
	static struct bt_pub_key_cb pub_key_cb;
	const size_t offset = offsetof(struct bt_mesh_prov_link, auth);

	pub_key_cb.func = func ? func : pub_key_ready;

	/* Disable Attention Timer if it was set */
	if (bt_mesh_prov_link.conf_inputs.invite[0]) {
		bt_mesh_attention(NULL, 0);
	}

	atomic_clear(bt_mesh_prov_link.flags);
	(void)memset((uint8_t *)&bt_mesh_prov_link + offset, 0,
		     sizeof(bt_mesh_prov_link) - offset);

	err = bt_pub_key_gen(&pub_key_cb);
	if (err) {
		BT_ERR("Failed to generate public key (%d)", err);
		return err;
	}
	return 0;
}

static bt_mesh_output_action_t output_action(uint8_t action)
{
	switch (action) {
	case OUTPUT_OOB_BLINK:
		return BT_MESH_BLINK;
	case OUTPUT_OOB_BEEP:
		return BT_MESH_BEEP;
	case OUTPUT_OOB_VIBRATE:
		return BT_MESH_VIBRATE;
	case OUTPUT_OOB_NUMBER:
		return BT_MESH_DISPLAY_NUMBER;
	case OUTPUT_OOB_STRING:
		return BT_MESH_DISPLAY_STRING;
	default:
		return BT_MESH_NO_OUTPUT;
	}
}

static bt_mesh_input_action_t input_action(uint8_t action)
{
	switch (action) {
	case INPUT_OOB_PUSH:
		return BT_MESH_PUSH;
	case INPUT_OOB_TWIST:
		return BT_MESH_TWIST;
	case INPUT_OOB_NUMBER:
		return BT_MESH_ENTER_NUMBER;
	case INPUT_OOB_STRING:
		return BT_MESH_ENTER_STRING;
	default:
		return BT_MESH_NO_INPUT;
	}
}

static int check_output_auth(bt_mesh_output_action_t output, uint8_t size)
{
	if (!output) {
		return -EINVAL;
	}

	if (!(bt_mesh_prov->output_actions & output)) {
		return -EINVAL;
	}

	if (size > bt_mesh_prov->output_size) {
		return -EINVAL;
	}

	return 0;
}

static int check_input_auth(bt_mesh_input_action_t input, uint8_t size)
{
	if (!input) {
		return -EINVAL;
	}

	if (!(bt_mesh_prov->input_actions & input)) {
		return -EINVAL;
	}

	if (size > bt_mesh_prov->input_size) {
		return -EINVAL;
	}

	return 0;
}

static void get_auth_string(char *str, uint8_t size)
{
	uint64_t value;

	bt_rand(&value, sizeof(value));

	static const char characters[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	for (int i = 0; i < size; i++) {
		/* pull base-36 digits: */
		int idx = value % 36;

		value = value / 36;
		str[i] = characters[idx];
	}

	str[size] = '\0';

	memcpy(bt_mesh_prov_link.auth, str, size);
	memset(bt_mesh_prov_link.auth + size, 0,
			sizeof(bt_mesh_prov_link.auth) - size);
}

static uint32_t get_auth_number(bt_mesh_output_action_t output,
		bt_mesh_input_action_t input, uint8_t size)
{
	const uint32_t divider[PROV_IO_OOB_SIZE_MAX] = { 10, 100, 1000, 10000,
			100000, 1000000, 10000000, 100000000 };
	uint32_t num = 0;

	bt_rand(&num, sizeof(num));

	if (output == BT_MESH_BLINK ||
	    output == BT_MESH_BEEP ||
	    output == BT_MESH_VIBRATE ||
	    input == BT_MESH_PUSH ||
	    input == BT_MESH_TWIST) {
		/* According to the Bluetooth Mesh Profile
		 * Specification Section 5.4.2.4, blink, beep
		 * vibrate, push and twist should be a random integer
		 * between 0 and 10^size, *exclusive*:
		 */
		num = (num % (divider[size - 1] - 1)) + 1;
	} else {
		num %= divider[size - 1];
	}

	sys_put_be32(num, &bt_mesh_prov_link.auth[12]);
	memset(bt_mesh_prov_link.auth, 0, 12);

	return num;
}

int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8_t size)
{
	bt_mesh_output_action_t output;
	bt_mesh_input_action_t input;
	int err;

	switch (method) {
	case AUTH_METHOD_NO_OOB:
		if (action || size) {
			return -EINVAL;
		}

		(void)memset(bt_mesh_prov_link.auth, 0, sizeof(bt_mesh_prov_link.auth));
		return 0;
	case AUTH_METHOD_STATIC:
		if (action || size) {
			return -EINVAL;
		}

		atomic_set_bit(bt_mesh_prov_link.flags, OOB_STATIC_KEY);

		return 0;

	case AUTH_METHOD_OUTPUT:
		output = output_action(action);

		if (is_provisioner) {
			if (output == BT_MESH_DISPLAY_STRING) {
				input = BT_MESH_ENTER_STRING;
				atomic_set_bit(bt_mesh_prov_link.flags, WAIT_STRING);
			} else {
				input = BT_MESH_ENTER_NUMBER;
				atomic_set_bit(bt_mesh_prov_link.flags, WAIT_NUMBER);
			}

			return bt_mesh_prov->input(input, size);
		}

		err = check_output_auth(output, size);
		if (err) {
			return err;
		}

		if (output == BT_MESH_DISPLAY_STRING) {
			char str[9];

			atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE);
			get_auth_string(str, size);
			return bt_mesh_prov->output_string(str);
		}

		atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE);
		return bt_mesh_prov->output_number(output,
				get_auth_number(output, BT_MESH_NO_INPUT, size));

	case AUTH_METHOD_INPUT:
		input = input_action(action);

		if (!is_provisioner) {
			err = check_input_auth(input, size);
			if (err) {
				return err;
			}

			if (input == BT_MESH_ENTER_STRING) {
				atomic_set_bit(bt_mesh_prov_link.flags, WAIT_STRING);
			} else {
				atomic_set_bit(bt_mesh_prov_link.flags, WAIT_NUMBER);
			}

			return bt_mesh_prov->input(input, size);
		}

		if (input == BT_MESH_ENTER_STRING) {
			char str[9];

			atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE);
			get_auth_string(str, size);
			return bt_mesh_prov->output_string(str);
		}

		atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE);
		output = BT_MESH_DISPLAY_NUMBER;
		return bt_mesh_prov->output_number(output,
				get_auth_number(BT_MESH_NO_OUTPUT, input, size));

	default:
		return -EINVAL;
	}
}

int bt_mesh_input_number(uint32_t num)
{
	BT_DBG("%u", num);

	if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_NUMBER)) {
		return -EINVAL;
	}

	sys_put_be32(num, &bt_mesh_prov_link.auth[12]);

	bt_mesh_prov_link.role->input_complete();

	return 0;
}

int bt_mesh_input_string(const char *str)
{
	BT_DBG("%s", str);

	if (strlen(str) > PROV_IO_OOB_SIZE_MAX ||
			strlen(str) > bt_mesh_prov_link.oob_size) {
		return -ENOTSUP;
	}

	if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_STRING)) {
		return -EINVAL;
	}

	strcpy((char *)bt_mesh_prov_link.auth, str);

	bt_mesh_prov_link.role->input_complete();

	return 0;
}

const struct bt_mesh_prov *bt_mesh_prov_get(void)
{
	return bt_mesh_prov;
}

bool bt_mesh_prov_active(void)
{
	return atomic_test_bit(bt_mesh_prov_link.flags, LINK_ACTIVE);
}

static void prov_recv(const struct prov_bearer *bearer, void *cb_data,
		      struct net_buf_simple *buf)
{
	static const uint8_t op_len[10] = {
		[PROV_INVITE]         = PDU_LEN_INVITE,
		[PROV_CAPABILITIES]   = PDU_LEN_CAPABILITIES,
		[PROV_START]          = PDU_LEN_START,
		[PROV_PUB_KEY]        = PDU_LEN_PUB_KEY,
		[PROV_INPUT_COMPLETE] = PDU_LEN_INPUT_COMPLETE,
		[PROV_CONFIRM]        = PDU_LEN_CONFIRM,
		[PROV_RANDOM]         = PDU_LEN_RANDOM,
		[PROV_DATA]           = PDU_LEN_DATA,
		[PROV_COMPLETE]       = PDU_LEN_COMPLETE,
		[PROV_FAILED]         = PDU_LEN_FAILED,
	};

	uint8_t type = buf->data[0];

	BT_DBG("type 0x%02x len %u", type, buf->len);

	if (type >= ARRAY_SIZE(bt_mesh_prov_link.role->op)) {
		BT_ERR("Unknown provisioning PDU type 0x%02x", type);
		bt_mesh_prov_link.role->error(PROV_ERR_NVAL_PDU);
		return;
	}

	if ((type != PROV_FAILED && type != bt_mesh_prov_link.expect) ||
	    !bt_mesh_prov_link.role->op[type]) {
		BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, bt_mesh_prov_link.expect);
		bt_mesh_prov_link.role->error(PROV_ERR_UNEXP_PDU);
		return;
	}

	if (1 + op_len[type] != buf->len) {
		BT_ERR("Invalid length %u for type 0x%02x", buf->len, type);
		bt_mesh_prov_link.role->error(PROV_ERR_NVAL_FMT);
		return;
	}

	bt_mesh_prov_link.role->op[type](&buf->data[1]);
}

static void prov_link_opened(const struct prov_bearer *bearer, void *cb_data)
{
	atomic_set_bit(bt_mesh_prov_link.flags, LINK_ACTIVE);

	if (bt_mesh_prov->link_open) {
		bt_mesh_prov->link_open(bearer->type);
	}

	bt_mesh_prov_link.bearer = bearer;

	if (bt_mesh_prov_link.role->link_opened) {
		bt_mesh_prov_link.role->link_opened();
	}
}

static void prov_link_closed(const struct prov_bearer *bearer, void *cb_data,
			     enum prov_bearer_link_status reason)
{
	BT_DBG("%u", reason);

	if (bt_mesh_prov_link.role->link_closed) {
		bt_mesh_prov_link.role->link_closed();
	}

	if (bt_mesh_prov->link_close) {
		bt_mesh_prov->link_close(bearer->type);
	}
}

static void prov_bearer_error(const struct prov_bearer *bearer, void *cb_data,
			      uint8_t err)
{
	if (bt_mesh_prov_link.role->error) {
		bt_mesh_prov_link.role->error(err);
	}
}

static const struct prov_bearer_cb prov_bearer_cb = {
	.link_opened = prov_link_opened,
	.link_closed = prov_link_closed,
	.error = prov_bearer_error,
	.recv = prov_recv,
};

const struct prov_bearer_cb *bt_mesh_prov_bearer_cb_get(void)
{
	return &prov_bearer_cb;
}

void bt_mesh_prov_complete(uint16_t net_idx, uint16_t addr)
{
	if (bt_mesh_prov->complete) {
		bt_mesh_prov->complete(net_idx, addr);
	}
}

void bt_mesh_prov_reset(void)
{
	if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
		pb_adv_reset();
	}

	if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
		pb_gatt_reset();
	}

	bt_mesh_prov_reset_state(NULL);

	if (bt_mesh_prov->reset) {
		bt_mesh_prov->reset();
	}
}

int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
{
	if (!prov_info) {
		BT_ERR("No provisioning context provided");
		return -EINVAL;
	}

	bt_mesh_prov = prov_info;

	if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
		pb_adv_init();
	}

	if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
		pb_gatt_init();
	}

	return bt_mesh_prov_reset_state(NULL);
}
