/* Copyright (c) 2023 Nordic Semiconductor ASA
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/l2cap.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>

#include "../common_defs.h"

#include "../testlib/att_read.h"
#include "../testlib/bs_macro.h"
#include "../testlib/connect.h"
#include "../testlib/scan.h"
#include "../testlib/security.h"

LOG_MODULE_REGISTER(client, LOG_LEVEL_DBG);

#define BT_LOCAL_ATT_MTU_EATT MIN(BT_L2CAP_SDU_RX_MTU, BT_L2CAP_SDU_TX_MTU)
#define BT_LOCAL_ATT_MTU_UATT MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU)
#define BT_ATT_BUF_SIZE	      MAX(BT_LOCAL_ATT_MTU_UATT, BT_LOCAL_ATT_MTU_EATT)

void test_long_read(struct bt_conn *conn, enum bt_att_chan_opt bearer)
{
	/* The handle will be discovered in the first switch case. */
	uint16_t handle = 0;

	/* Loop over the switch cases. */
	for (int i = 0; i < 3; i++) {
		int err;
		uint16_t actual_read_len;
		uint16_t remote_read_send_len;

		NET_BUF_SIMPLE_DEFINE(attr_value, sizeof(remote_read_send_len));

		/* Exercise various ATT read operations. */
		switch (i) {
		case 0:
			LOG_INF("ATT_READ_BY_TYPE");
			/* Aka. "read by uuid". */
			err = bt_testlib_att_read_by_type_sync(&attr_value, &actual_read_len,
							       &handle, conn, bearer,
							       MTU_VALIDATION_CHRC, 1, 0xffff);
			break;
		case 1:
			LOG_INF("ATT_READ");
			/* Arg `offset == 0`: the stack should choose ATT_READ PDU. */
			err = bt_testlib_att_read_by_handle_sync(&attr_value, &actual_read_len,
								 conn, bearer, handle, 0);
			break;
		case 2:
			LOG_INF("ATT_READ_BLOB");
			/* Arg `offset != 0`: the stack should choose ATT_READ_BLOB PDU. */
			err = bt_testlib_att_read_by_handle_sync(&attr_value, &actual_read_len,
								 conn, bearer, handle, 1);
			break;
		}

		__ASSERT_NO_MSG(!err);
		__ASSERT(attr_value.len >= sizeof(remote_read_send_len),
			 "Remote sent too little data.");
		remote_read_send_len = net_buf_simple_pull_le16(&attr_value);
		__ASSERT(remote_read_send_len == actual_read_len, "Length mismatch. %u %u",
			 remote_read_send_len, actual_read_len);
	}
}

void the_test(void)
{
	bt_addr_le_t scan_result;
	int err;
	struct bt_conn *conn = NULL;

	err = bt_enable(NULL);
	__ASSERT_NO_MSG(!err);

	err = bt_testlib_scan_find_name(&scan_result, "d1");
	__ASSERT_NO_MSG(!err);

	err = bt_testlib_connect(&scan_result, &conn);
	__ASSERT_NO_MSG(!err);

	/* Establish EATT bearers. */
	err = bt_testlib_secure(conn, BT_SECURITY_L2);
	__ASSERT_NO_MSG(!err);

	while (bt_eatt_count(conn) == 0) {
		LOG_DBG("E..");
		k_msleep(100);
	};
	LOG_DBG("EATT");

	test_long_read(conn, BT_ATT_CHAN_OPT_UNENHANCED_ONLY);
	test_long_read(conn, BT_ATT_CHAN_OPT_ENHANCED_ONLY);

	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	__ASSERT_NO_MSG(!err);

	bt_conn_unref(conn);
	conn = NULL;

	PASS("PASS\n");
}
