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

#include <zephyr/kernel.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;
	}

	memcpy(bt_mesh_prov_link.auth, str, strlen(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)) {
		bt_mesh_pb_adv_reset();
	}

	if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
		bt_mesh_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)) {
		bt_mesh_pb_adv_init();
	}

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

	return bt_mesh_prov_reset_state(NULL);
}
