/*
 * Copyright (c) 2017 Intel Corporation
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <bluetooth/mesh.h>
#include <bluetooth/conn.h>
#include "net.h"
#include "proxy.h"
#include "adv.h"
#include "host/ecc.h"
#include "prov.h"
#include "pb_gatt.h"
#include "proxy_msg.h"
#include "pb_gatt_srv.h"
#include "pb_gatt_cli.h"

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

struct prov_bearer_send_cb {
	prov_bearer_send_complete_t cb;
	void *cb_data;
};

struct prov_link {
	struct bt_conn *conn;
	const struct prov_bearer_cb *cb;
	void *cb_data;
	struct prov_bearer_send_cb comp;
	struct k_work_delayable prot_timer;
};

static struct prov_link link;

static void reset_state(void)
{
	if (link.conn) {
		bt_conn_unref(link.conn);
		link.conn = NULL;
	}

	/* If this fails, the protocol timeout handler will exit early. */
	(void)k_work_cancel_delayable(&link.prot_timer);
}

static void link_closed(enum prov_bearer_link_status status)
{
	const struct prov_bearer_cb *cb = link.cb;
	void *cb_data = link.cb_data;

	reset_state();

	cb->link_closed(&pb_gatt, cb_data, status);
}

static void protocol_timeout(struct k_work *work)
{
	if (!atomic_test_bit(bt_mesh_prov_link.flags, LINK_ACTIVE)) {
		return;
	}

	/* If connection failed or timeout, not allow establish connection */
	if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT_CLIENT) &&
	    atomic_test_bit(bt_mesh_prov_link.flags, PROVISIONER)) {
		if (link.conn) {
			(void)bt_conn_disconnect(link.conn,
						 BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		} else {
			(void)bt_mesh_pb_gatt_cli_setup(NULL);
		}
	}

	BT_DBG("Protocol timeout");

	link_closed(PROV_BEARER_LINK_STATUS_TIMEOUT);
}

int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf)
{
	BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));

	if (link.conn != conn || !link.cb) {
		BT_WARN("Data for unexpected connection");
		return -ENOTCONN;
	}

	if (buf->len < 1) {
		BT_WARN("Too short provisioning packet (len %u)", buf->len);
		return -EINVAL;
	}

	k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT);

	link.cb->recv(&pb_gatt, link.cb_data, buf);

	return 0;
}

int bt_mesh_pb_gatt_start(struct bt_conn *conn)
{
	BT_DBG("conn %p", (void *)conn);

	if (link.conn) {
		return -EBUSY;
	}

	link.conn = bt_conn_ref(conn);
	k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT);

	link.cb->link_opened(&pb_gatt, link.cb_data);

	return 0;
}

int bt_mesh_pb_gatt_close(struct bt_conn *conn)
{
	BT_DBG("conn %p", (void *)conn);

	if (link.conn != conn) {
		BT_DBG("Not connected");
		return -ENOTCONN;
	}

	link_closed(PROV_BEARER_LINK_STATUS_SUCCESS);

	return 0;
}

#if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
int bt_mesh_pb_gatt_cli_start(struct bt_conn *conn)
{
	BT_DBG("conn %p", (void *)conn);

	if (link.conn) {
		return -EBUSY;
	}

	link.conn = bt_conn_ref(conn);
	k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT);

	return 0;
}

int bt_mesh_pb_gatt_cli_open(struct bt_conn *conn)
{
	BT_DBG("conn %p", (void *)conn);

	if (link.conn != conn) {
		BT_DBG("Not connected");
		return -ENOTCONN;
	}

	link.cb->link_opened(&pb_gatt, link.cb_data);

	return 0;
}

static int prov_link_open(const uint8_t uuid[16], k_timeout_t timeout,
			  const struct prov_bearer_cb *cb, void *cb_data)
{
	BT_DBG("uuid %s", bt_hex(uuid, 16));

	link.cb = cb;
	link.cb_data = cb_data;

	k_work_reschedule(&link.prot_timer, timeout);

	return bt_mesh_pb_gatt_cli_setup(uuid);
}

static void prov_link_close(enum prov_bearer_link_status status)
{
	(void)bt_conn_disconnect(link.conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}
#endif

#if defined(CONFIG_BT_MESH_PB_GATT)
static int link_accept(const struct prov_bearer_cb *cb, void *cb_data)
{
	int err;

	err = bt_mesh_adv_enable();
	if (err) {
		BT_ERR("Failed enabling advertiser");
		return err;
	}

	(void)bt_mesh_pb_gatt_srv_enable();
	bt_mesh_adv_gatt_update();

	link.cb = cb;
	link.cb_data = cb_data;

	return 0;
}
#endif

static void buf_send_end(struct bt_conn *conn, void *user_data)
{
	if (link.comp.cb) {
		link.comp.cb(0, link.comp.cb_data);
	}
}

static int buf_send(struct net_buf_simple *buf, prov_bearer_send_complete_t cb,
		    void *cb_data)
{
	if (!link.conn) {
		return -ENOTCONN;
	}

	link.comp.cb = cb;
	link.comp.cb_data = cb_data;

	k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT);

	return bt_mesh_proxy_msg_send(link.conn, BT_MESH_PROXY_PROV,
				      buf, buf_send_end, NULL);
}

static void clear_tx(void)
{
	/* No action */
}

void pb_gatt_init(void)
{
	k_work_init_delayable(&link.prot_timer, protocol_timeout);
}

void pb_gatt_reset(void)
{
	reset_state();
}

const struct prov_bearer pb_gatt = {
	.type = BT_MESH_PROV_GATT,
#if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
	.link_open = prov_link_open,
	.link_close = prov_link_close,
#endif
#if defined(CONFIG_BT_MESH_PB_GATT)
	.link_accept = link_accept,
#endif
	.send = buf_send,
	.clear_tx = clear_tx,
};
