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

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

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

#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>

#include <misc/util.h>

#define BT_DBG_ENABLED IS_ENABLED(NBLE_DEBUG_GAP)
#include "common/log.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 */
	u8_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 u8_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 u8_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 u8_t legacy_get_pair_method(struct bt_smp *smp, u8_t remote_io)
{
	u8_t local_io = get_io_capa();
	u8_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 u8_t get_auth(u8_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 u8_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, u8_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;
}
