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

#include <errno.h>
#include <atomic.h>

#include <zephyr.h>
#include <device.h>

#define BT_DBG_ENABLED IS_ENABLED(NBLE_DEBUG_GAP)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>

#include <misc/util.h>

#include "gap_internal.h"
#include "conn_internal.h"
#include "conn.h"

#define BT_SMP_IO_DISPLAY_ONLY			0x00
#define BT_SMP_IO_DISPLAY_YESNO			0x01
#define BT_SMP_IO_KEYBOARD_ONLY			0x02
#define BT_SMP_IO_NO_INPUT_OUTPUT		0x03
#define BT_SMP_IO_KEYBOARD_DISPLAY		0x04

#define BT_SMP_OOB_NOT_PRESENT			0x00
#define BT_SMP_OOB_PRESENT			0x01

#define BT_SMP_MIN_ENC_KEY_SIZE			7
#define BT_SMP_MAX_ENC_KEY_SIZE			16

enum {
	SMP_FLAG_CFM_DELAYED,	/* if confirm should be send when TK is valid */
	SMP_FLAG_ENC_PENDING,	/* if waiting for an encryption change event */
	SMP_FLAG_KEYS_DISTR,	/* if keys distribution phase is in progress */
	SMP_FLAG_PAIRING,	/* if pairing is in progress */
	SMP_FLAG_TIMEOUT,	/* if SMP timeout occurred */
	SMP_FLAG_SC,		/* if LE Secure Connections is used */
	SMP_FLAG_PKEY_SEND,	/* if should send Public Key when available */
	SMP_FLAG_DHKEY_PENDING,	/* if waiting for local DHKey */
	SMP_FLAG_DHKEY_SEND,	/* if should generate and send DHKey Check */
	SMP_FLAG_USER,		/* if waiting for user input */
	SMP_FLAG_BOND,		/* if bonding */
	SMP_FLAG_SC_DEBUG_KEY,	/* if Secure Connection are using debug key */
	SMP_FLAG_SEC_REQ,	/* if Security Request was sent/received */
};

enum pairing_method {
	JUST_WORKS,		/* JustWorks pairing */
	PASSKEY_INPUT,		/* Passkey Entry input */
	PASSKEY_DISPLAY,	/* Passkey Entry display */
	PASSKEY_CONFIRM,	/* Passkey confirm */
	PASSKEY_ROLE,		/* Passkey Entry depends on role */
};

struct bt_smp {
	/* The channel this context is associated with (nble conn object)*/
	struct bt_conn *conn;

	/* Flags for SMP state machine */
	atomic_t flags;

	/* Type of method used for pairing */
	uint8_t method;
};

static struct bt_smp bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN];

static struct bt_smp *smp_chan_get(struct bt_conn *conn)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) {
		struct bt_smp *smp = &bt_smp_pool[i];

		if (smp->conn == conn) {
			return smp;
		}
	}

	return NULL;
}

static void smp_reset(struct bt_smp *smp)
{
	smp->flags = 0;
	smp->method = 0;
	smp->conn = NULL;
}

void bt_smp_connected(struct bt_conn *conn)
{
	struct bt_smp *smp = NULL;
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) {
		smp = &bt_smp_pool[i];

		if (!smp->conn) {
			break;
		}
	}

	/* Reset flags and states */
	smp_reset(smp);

	smp->conn = conn;
}

void bt_smp_disconnected(struct bt_conn *conn)
{
	struct bt_smp *smp = smp_chan_get(conn);

	if (smp) {
		smp_reset(smp);
	}
}

/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
static const uint8_t gen_method_legacy[5 /* remote */][5 /* local */] = {
	{ JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT },
	{ JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT },
	{ PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS,
	  PASSKEY_DISPLAY },
	{ JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS },
	{ PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS,
	  PASSKEY_ROLE },
};

static uint8_t get_io_capa(void)
{
	if (!nble.auth) {
		return BT_SMP_IO_NO_INPUT_OUTPUT;
	}

	/* Passkey Confirmation is valid only for LE SC */
	if (nble.auth->passkey_display && nble.auth->passkey_entry &&
	    nble.auth->passkey_confirm) {
		return BT_SMP_IO_KEYBOARD_DISPLAY;
	}

	/* DisplayYesNo is useful only for LE SC */
	if (nble.auth->passkey_display &&
	    nble.auth->passkey_confirm) {
		return BT_SMP_IO_DISPLAY_YESNO;
	}

	if (nble.auth->passkey_entry) {
		return BT_SMP_IO_KEYBOARD_ONLY;
	}

	if (nble.auth->passkey_display) {
		return BT_SMP_IO_DISPLAY_ONLY;
	}

	return BT_SMP_IO_NO_INPUT_OUTPUT;
}

static uint8_t legacy_get_pair_method(struct bt_smp *smp, uint8_t remote_io)
{
	uint8_t local_io = get_io_capa();
	uint8_t method;

	if (remote_io > BT_SMP_IO_KEYBOARD_DISPLAY)
		return JUST_WORKS;

	method = gen_method_legacy[remote_io][local_io];

	/* if both sides have KeyboardDisplay capabilities, initiator displays
	 * and responder inputs
	 */
	if (method == PASSKEY_ROLE) {
		if (smp->conn->role == BT_HCI_ROLE_MASTER) {
			method = PASSKEY_DISPLAY;
		} else {
			method = PASSKEY_INPUT;
		}
	}

	BT_DBG("local_io %u remote_io %u method %u", local_io, remote_io,
	       method);

	return method;
}

static uint8_t get_auth(uint8_t auth)
{
	if (get_io_capa() == BT_SMP_IO_NO_INPUT_OUTPUT) {
		auth &= ~(BT_SMP_AUTH_MITM);
	} else {
		auth |= BT_SMP_AUTH_MITM;
	}

	return auth;
}

static uint8_t legacy_pairing_req(struct bt_smp *smp,
				  const struct nble_sec_param *par)
{
	struct nble_sm_pairing_response_req req;

	smp->method = legacy_get_pair_method(smp, par->io_capabilities);

	BT_DBG("method %u io_caps %u", smp->method, par->io_capabilities);

	/* ask for consent if pairing is not due to sending SecReq*/
	if (smp->method == JUST_WORKS &&
	    !atomic_test_bit(&smp->flags, SMP_FLAG_SEC_REQ) &&
	    nble.auth && nble.auth->pairing_confirm) {
		atomic_set_bit(&smp->flags, SMP_FLAG_USER);
		nble.auth->pairing_confirm(smp->conn);
		return 0;
	}

	req.conn = smp->conn;
	req.conn_handle = smp->conn->handle;
	req.params.auth = get_auth(par->auth);
	req.params.io_capabilities = get_io_capa();
	req.params.max_key_size = par->max_key_size;
	req.params.min_key_size = par->min_key_size;
	req.params.oob_flag = BT_SMP_OOB_NOT_PRESENT;

	nble_sm_pairing_response_req(&req);

	return 0;
}

void on_nble_sm_pairing_request_evt(const struct nble_sm_pairing_request_evt *evt)
{
	struct bt_conn *conn;
	struct bt_smp *smp;

	BT_DBG("");

	conn = bt_conn_lookup_handle(evt->conn_handle);
	if (!conn) {
		BT_ERR("Unable to find conn for handle %u", evt->conn_handle);
		return;
	}

	smp = smp_chan_get(conn);
	if (!smp) {
		BT_ERR("No smp");
		bt_conn_unref(conn);
		return;
	}

	atomic_set_bit(&smp->flags, SMP_FLAG_PAIRING);

	legacy_pairing_req(smp, &evt->sec_param);

	bt_conn_unref(conn);
}

static void nble_start_security(struct bt_conn *conn)
{
	struct nble_sm_security_req req = { 0 };

	req.conn = conn,
	req.conn_handle = conn->handle,
	req.params.auth =  get_auth(BT_SMP_AUTH_BONDING | BT_SMP_AUTH_MITM);
	req.params.io_capabilities = get_io_capa();
	req.params.max_key_size = BT_SMP_MAX_ENC_KEY_SIZE;
	req.params.min_key_size = BT_SMP_MIN_ENC_KEY_SIZE;
	req.params.oob_flag = BT_SMP_OOB_NOT_PRESENT;

	/**
	 * nble stack generates either a smp security or pairing request
	 * depending on role.
	 */
	nble_sm_security_req(&req);
}

int bt_smp_send_pairing_req(struct bt_conn *conn)
{
	struct bt_smp *smp;

	BT_DBG("");

	smp = smp_chan_get(conn);
	if (!smp) {
		return -ENOTCONN;
	}

	/* pairing is in progress */
	if (atomic_test_bit(&smp->flags, SMP_FLAG_PAIRING)) {
		return -EBUSY;
	}

	/* TODO: Verify sec level reachable */

	nble_start_security(conn);

	atomic_set_bit(&smp->flags, SMP_FLAG_PAIRING);

	return 0;
}
int bt_smp_send_security_req(struct bt_conn *conn)
{
	struct bt_smp *smp;

	BT_DBG("");

	smp = smp_chan_get(conn);
	if (!smp) {
		return -ENOTCONN;
	}

	/* pairing is in progress */
	if (atomic_test_bit(&smp->flags, SMP_FLAG_PAIRING)) {
		return -EBUSY;
	}

	/* TODO: Verify sec level reachable */

	nble_start_security(conn);

	atomic_set_bit(&smp->flags, SMP_FLAG_SEC_REQ);

	return 0;
}

void on_nble_sm_security_request_evt(const struct nble_sm_security_request_evt *evt)
{
	struct bt_conn *conn;
	struct bt_smp *smp;

	BT_DBG("");

	conn = bt_conn_lookup_handle(evt->conn_handle);
	if (!conn) {
		BT_ERR("Unable to find conn for handle %u", evt->conn_handle);
		return;
	}

	smp = smp_chan_get(conn);
	if (!smp) {
		BT_ERR("No smp");
		bt_conn_unref(conn);
		return;
	}

	BT_DBG("conn %p remote_io %u auth %u", conn,
	       evt->sec_param.io_capabilities, evt->sec_param.auth);

	smp->method = legacy_get_pair_method(smp,
					     evt->sec_param.io_capabilities);

	if (smp->method == JUST_WORKS &&
	    nble.auth && nble.auth->pairing_confirm) {
		atomic_set_bit(&smp->flags, SMP_FLAG_USER);
		nble.auth->pairing_confirm(smp->conn);
		goto done;
	}

	bt_smp_send_pairing_req(conn);

done:
	atomic_set_bit(&smp->flags, SMP_FLAG_SEC_REQ);
	bt_conn_unref(conn);
}

void on_nble_sm_common_rsp(const struct nble_sm_common_rsp *rsp)
{
	if (rsp->status) {
		BT_ERR("GAP SM request failed:  conn %p err %d", rsp->conn,
		       rsp->status);

		/* TODO: Handle error */
		return;
	}
}

void on_nble_sm_status_evt(const struct nble_sm_status_evt *ev)
{
	struct bt_conn *conn;
	struct bt_smp *smp;

	conn = bt_conn_lookup_handle(ev->conn_handle);
	if (!conn) {
		BT_ERR("Unable to find conn for handle %u", ev->conn_handle);
		return;
	}

	smp = smp_chan_get(conn);
	if (!smp) {
		BT_ERR("No smp for conn %p", conn);
		return;
	}

	BT_DBG("conn %p status %d evt_type %d sec_level %d enc_size %u",
	       conn, ev->status, ev->evt_type, ev->enc_link_sec.sec_level,
	       ev->enc_link_sec.enc_size);

	switch (ev->evt_type) {
	case NBLE_GAP_SM_EVT_BONDING_COMPLETE:
		BT_DBG("Bonding complete");
		if (ev->status) {
			if (nble.auth && nble.auth->cancel) {
				nble.auth->cancel(conn);
			}
		}
		smp_reset(smp);
		break;
	case NBLE_GAP_SM_EVT_LINK_ENCRYPTED:
		BT_DBG("Link encrypted");
		break;
	case NBLE_GAP_SM_EVT_LINK_SECURITY_CHANGE:
		BT_DBG("Security change");
		break;
	default:
		BT_ERR("Unknown event %d", ev->evt_type);
		break;
	}

	bt_conn_unref(conn);
}

void on_nble_sm_passkey_disp_evt(const struct nble_sm_passkey_disp_evt *ev)
{
	struct bt_conn *conn;

	conn = bt_conn_lookup_handle(ev->conn_handle);
	if (!conn) {
		BT_ERR("Unable to find conn for handle %u", ev->conn_handle);
		return;
	}

	BT_DBG("conn %p passkey %u", conn, ev->passkey);

	/* TODO: Check shall we store io_caps globally */
	if (get_io_capa() == BT_SMP_IO_DISPLAY_YESNO) {
		if (nble.auth && nble.auth->passkey_confirm) {
			nble.auth->passkey_confirm(conn, ev->passkey);
		}
	} else {
		if (nble.auth && nble.auth->passkey_display) {
			nble.auth->passkey_display(conn, ev->passkey);
		}
	}

	bt_conn_unref(conn);
}

void on_nble_sm_passkey_req_evt(const struct nble_sm_passkey_req_evt *ev)
{
	struct bt_conn *conn;
	struct bt_smp *smp;

	conn = bt_conn_lookup_handle(ev->conn_handle);
	if (!conn) {
		BT_ERR("Unable to find conn for handle %u", ev->conn_handle);
		return;
	}

	smp = smp_chan_get(conn);
	if (!smp) {
		bt_conn_unref(conn);
		return;
	}

	BT_DBG("conn %p key_type %u", conn, ev->key_type);

	/* Set user input expected flag */
	atomic_set_bit(&smp->flags, SMP_FLAG_USER);

	if (ev->key_type == NBLE_GAP_SM_PK_PASSKEY) {
		if (nble.auth && nble.auth->passkey_entry) {
			nble.auth->passkey_entry(conn);
		}
	}

	bt_conn_unref(conn);
}

static void nble_security_reply(struct bt_conn *conn,
				struct nble_sm_passkey *par)
{
	struct nble_sm_passkey_reply_req rsp = {
		.conn = conn,
		.conn_handle = conn->handle,
	};

	memcpy(&rsp.params, par, sizeof(*par));

	nble_sm_passkey_reply_req(&rsp);
}

static int sm_error(struct bt_conn *conn, uint8_t reason)
{
	struct nble_sm_passkey params;

	params.type = NBLE_GAP_SM_REJECT;
	params.reason = reason;

	nble_security_reply(conn, &params);

	return 0;
}

static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey)
{
	struct nble_sm_passkey pkey = {
		.type = NBLE_SM_PK_PASSKEY,
		.passkey = passkey,
	};

	BT_DBG("passkey %u", passkey);

	nble_security_reply(smp->conn, &pkey);
}

int bt_smp_auth_cancel(struct bt_conn *conn)
{
	BT_DBG("");

	return sm_error(conn, BT_SMP_ERR_PASSKEY_ENTRY_FAILED);
}

int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)
{
	struct bt_smp *smp;

	BT_DBG("passkey %u", passkey);

	smp = smp_chan_get(conn);
	if (!smp) {
		return -EINVAL;
	}

	if (!atomic_test_and_clear_bit(&smp->flags, SMP_FLAG_USER)) {
		BT_ERR("Not expected user input");
		return -EINVAL;
	}

	if (!atomic_test_bit(&smp->flags, SMP_FLAG_SC)) {
		legacy_passkey_entry(smp, passkey);
		return 0;
	}

	return 0;
}

int bt_smp_auth_pairing_confirm(struct bt_conn *conn)
{
	struct bt_smp *smp;
	struct nble_sm_pairing_response_req req;

	BT_DBG("");

	smp = smp_chan_get(conn);
	if (!smp) {
		return -ENOTCONN;
	}

	if (!atomic_test_and_clear_bit(&smp->flags, SMP_FLAG_USER)) {
		BT_ERR("Not expected user input");
		return -EINVAL;
	}

	if (conn->role == BT_CONN_ROLE_MASTER) {
		bt_smp_send_pairing_req(conn);
	} else {
		req.conn = conn;
		req.conn_handle = conn->handle;
		req.params.auth = get_auth(BT_SMP_AUTH_BONDING);
		req.params.io_capabilities = get_io_capa();
		req.params.max_key_size = BT_SMP_MAX_ENC_KEY_SIZE;
		req.params.min_key_size = BT_SMP_MIN_ENC_KEY_SIZE;
		req.params.oob_flag = BT_SMP_OOB_NOT_PRESENT;

		nble_sm_pairing_response_req(&req);
	}

	return 0;
}

int bt_smp_init(void)
{
	BT_DBG("");

	nble_get_bda_req(NULL);

	return 0;
}
