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

#include <zephyr/bluetooth/hci.h>

#include "common/bt_str.h"

#define LOG_LEVEL CONFIG_BT_MESH_PROV_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_pb_gatt);

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(&bt_mesh_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);
		}
	}

	LOG_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)
{
	LOG_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));

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

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

	k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get());

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

	return 0;
}

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

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

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

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

	return 0;
}

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

	if (link.conn != conn) {
		LOG_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)
{
	LOG_DBG("conn %p", (void *)conn);

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

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

	return 0;
}

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

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

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

	return 0;
}

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

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

	k_work_reschedule(&link.prot_timer, K_SECONDS(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) {
		LOG_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, bt_mesh_prov_protocol_timeout_get());

	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 bt_mesh_pb_gatt_init(void)
{
	k_work_init_delayable(&link.prot_timer, protocol_timeout);
}

void bt_mesh_pb_gatt_reset(void)
{
	reset_state();
}

const struct prov_bearer bt_mesh_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,
};
