/*
 * Copyright (c) 2021 Xiaomi Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/zephyr.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/mesh.h>

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

#include "mesh.h"
#include "adv.h"
#include "net.h"
#include "rpl.h"
#include "transport.h"
#include "host/ecc.h"
#include "prov.h"
#include "pb_gatt.h"
#include "beacon.h"
#include "foundation.h"
#include "access.h"
#include "proxy.h"
#include "gatt_cli.h"
#include "proxy_msg.h"

static struct {
	const uint8_t *target;
	struct bt_mesh_proxy_role *srv;
} server;

static void pb_gatt_msg_recv(struct bt_mesh_proxy_role *role)
{
	switch (role->msg_type) {
	case BT_MESH_PROXY_PROV:
		BT_DBG("Mesh Provisioning PDU");
		bt_mesh_pb_gatt_recv(role->conn, &role->buf);
		break;
	default:
		BT_WARN("Unhandled Message Type 0x%02x", role->msg_type);
		break;
	}
}

static void pb_gatt_connected(struct bt_conn *conn, void *user_data)
{
	server.srv = bt_mesh_proxy_role_setup(conn, bt_mesh_gatt_send,
					      pb_gatt_msg_recv);

	server.target = NULL;

	bt_mesh_pb_gatt_cli_start(conn);
}

static void pb_gatt_link_open(struct bt_conn *conn)
{
	bt_mesh_pb_gatt_cli_open(conn);
}

static void pb_gatt_disconnected(struct bt_conn *conn)
{
	bt_mesh_pb_gatt_close(conn);

	bt_mesh_proxy_role_cleanup(server.srv);

	server.srv = NULL;
}

static const struct bt_mesh_gatt_cli pbgatt = {
	.srv_uuid		= BT_UUID_INIT_16(BT_UUID_MESH_PROV_VAL),
	.data_in_uuid		= BT_UUID_INIT_16(BT_UUID_MESH_PROV_DATA_IN_VAL),
	.data_out_uuid		= BT_UUID_INIT_16(BT_UUID_MESH_PROV_DATA_OUT_VAL),
	.data_out_cccd_uuid	= BT_UUID_INIT_16(BT_UUID_GATT_CCC_VAL),

	.connected		= pb_gatt_connected,
	.link_open		= pb_gatt_link_open,
	.disconnected		= pb_gatt_disconnected
};

int bt_mesh_pb_gatt_cli_setup(const uint8_t uuid[16])
{
	if (server.srv) {
		return -EBUSY;
	}

	server.target = uuid;

	return 0;
}

void bt_mesh_pb_gatt_cli_adv_recv(const struct bt_le_scan_recv_info *info,
				  struct net_buf_simple *buf)
{
	uint8_t *uuid;
	bt_mesh_prov_oob_info_t oob_info;

	if (server.srv) {
		return;
	}

	if (buf->len != 18) {
		return;
	}

	uuid = net_buf_simple_pull_mem(buf, 16);

	if (server.target &&
	    !memcmp(server.target, uuid, 16)) {
		(void)bt_mesh_gatt_cli_connect(info->addr, &pbgatt, NULL);
		return;
	}

	if (!bt_mesh_prov->unprovisioned_beacon_gatt) {
		return;
	}

	oob_info = (bt_mesh_prov_oob_info_t)net_buf_simple_pull_le16(buf);

	bt_mesh_prov->unprovisioned_beacon_gatt(uuid, oob_info);
}
