/*
 * Copyright (c) 2022 Vestas Wind Systems A/S
 * Copyright (c) 2019 Alexander Wachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/can.h>
#include <zephyr/ztest.h>

/**
 * @addtogroup t_can_driver
 * @{
 * @defgroup t_can_canfd test_can_canfd
 * @}
 */

/**
 * Test bitrates in bits/second.
 */
#define TEST_BITRATE 1000000

/**
 * Test sample points in per mille.
 */
#define TEST_SAMPLE_POINT 750


/**
 * @brief Test timeouts.
 */
#define TEST_SEND_TIMEOUT    K_MSEC(100)
#define TEST_RECEIVE_TIMEOUT K_MSEC(100)

/**
 * @brief Standard (11-bit) CAN IDs used for testing.
 */
#define TEST_CAN_STD_ID_1      0x555
#define TEST_CAN_STD_ID_2      0x556

/**
 * @brief Global variables.
 */
static const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
static struct k_sem rx_callback_sem;
static struct k_sem tx_callback_sem;

CAN_MSGQ_DEFINE(can_msgq, 5);

/**
 * @brief Standard (11-bit) CAN ID frame 1.
 */
const struct can_frame test_std_frame_1 = {
	.id_type = CAN_STANDARD_IDENTIFIER,
	.rtr     = CAN_DATAFRAME,
	.id      = TEST_CAN_STD_ID_1,
	.dlc     = 8,
	.data    = { 1, 2, 3, 4, 5, 6, 7, 8 }
};

/**
 * @brief Standard (11-bit) CAN ID frame 2.
 */
const struct can_frame test_std_frame_2 = {
	.id_type = CAN_STANDARD_IDENTIFIER,
	.rtr     = CAN_DATAFRAME,
	.id      = TEST_CAN_STD_ID_2,
	.dlc     = 8,
	.data    = { 1, 2, 3, 4, 5, 6, 7, 8 }
};

/**
 * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload.
 */
const struct can_frame test_std_frame_fd_1 = {
	.id  = TEST_CAN_STD_ID_1,
	.fd      = 1,
	.rtr     = CAN_DATAFRAME,
	.id_type = CAN_STANDARD_IDENTIFIER,
	.dlc     = 0xf,
	.brs     = 1,
	.data    = { 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
		    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
		    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
		    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
		    61, 62, 63, 64 }
};

/**
 * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload.
 */
const struct can_frame test_std_frame_fd_2 = {
	.id  = TEST_CAN_STD_ID_2,
	.fd      = 1,
	.rtr     = CAN_DATAFRAME,
	.id_type = CAN_STANDARD_IDENTIFIER,
	.dlc     = 0xf,
	.brs     = 1,
	.data    = { 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
		    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
		    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
		    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
		    61, 62, 63, 64 }
};

/**
 * @brief Standard (11-bit) CAN ID filter 1.
 */
const struct can_filter test_std_filter_1 = {
	.id_type = CAN_STANDARD_IDENTIFIER,
	.rtr = CAN_DATAFRAME,
	.id = TEST_CAN_STD_ID_1,
	.rtr_mask = 1,
	.id_mask = CAN_STD_ID_MASK
};

/**
 * @brief Standard (11-bit) CAN ID filter 2.
 */
const struct can_filter test_std_filter_2 = {
	.id_type = CAN_STANDARD_IDENTIFIER,
	.rtr = CAN_DATAFRAME,
	.id = TEST_CAN_STD_ID_2,
	.rtr_mask = 1,
	.id_mask = CAN_STD_ID_MASK
};

/**
 * @brief Assert that two CAN frames are equal.
 *
 * @param frame1  First CAN frame.
 * @param frame2  Second CAN frame.
 */
static inline void assert_frame_equal(const struct can_frame *frame1,
				      const struct can_frame *frame2)
{
	zassert_equal(frame1->id_type, frame2->id_type, "ID type does not match");
	zassert_equal(frame1->fd, frame2->fd, "FD bit does not match");
	zassert_equal(frame1->rtr, frame2->rtr, "RTR bit does not match");
	zassert_equal(frame1->id, frame2->id, "ID does not match");
	zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match");
	zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ");
}

static void tx_std_callback_1(const struct device *dev, int error, void *user_data)
{
	const struct can_frame *frame = user_data;

	k_sem_give(&tx_callback_sem);

	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal(frame->id, TEST_CAN_STD_ID_1, "ID does not match");
}

static void tx_std_callback_2(const struct device *dev, int error, void *user_data)
{
	const struct can_frame *frame = user_data;

	k_sem_give(&tx_callback_sem);

	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal(frame->id, TEST_CAN_STD_ID_2, "ID does not match");
}

static void rx_std_callback_1(const struct device *dev, struct can_frame *frame, void *user_data)
{
	struct can_filter *filter = user_data;

	assert_frame_equal(frame, &test_std_frame_1);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_filter_1, "filter does not match");

	k_sem_give(&rx_callback_sem);
}

static void rx_std_callback_2(const struct device *dev, struct can_frame *frame, void *user_data)
{
	struct can_filter *filter = user_data;

	assert_frame_equal(frame, &test_std_frame_2);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_filter_2, "filter does not match");

	k_sem_give(&rx_callback_sem);
}

static void rx_std_callback_fd_1(const struct device *dev, struct can_frame *frame,
				 void *user_data)
{
	struct can_filter *filter = user_data;

	assert_frame_equal(frame, &test_std_frame_fd_1);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_filter_1, "filter does not match");

	k_sem_give(&rx_callback_sem);
}

static void rx_std_callback_fd_2(const struct device *dev, struct can_frame *frame,
				 void *user_data)
{
	struct can_filter *filter = user_data;

	assert_frame_equal(frame, &test_std_frame_fd_2);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_filter_2, "filter does not match");

	k_sem_give(&rx_callback_sem);
}

/**
 * @brief Send a CAN test frame with asserts.
 *
 * This function will block until the frame is transmitted or a test timeout
 * occurs.
 *
 * @param dev   Pointer to the device structure for the driver instance.
 * @param frame Pointer to the CAN frame to send.
 */
static void send_test_frame(const struct device *dev, const struct can_frame *frame)
{
	int err;

	err = can_send(dev, frame, TEST_SEND_TIMEOUT, NULL, NULL);
	zassert_not_equal(err, -EBUSY, "arbitration lost in loopback mode");
	zassert_equal(err, 0, "failed to send frame (err %d)", err);
}

/**
 * @brief Send a CAN test frame with asserts.
 *
 * This function will block until the frame is queued or a test timeout
 * occurs.
 *
 * @param dev      Pointer to the device structure for the driver instance.
 * @param frame    Pointer to the CAN frame to send.
 * @param callback Transmit callback function.
 */
static void send_test_frame_nowait(const struct device *dev, const struct can_frame *frame,
				   can_tx_callback_t callback)
{
	int err;

	err = can_send(dev, frame, TEST_SEND_TIMEOUT, callback, (void *)frame);
	zassert_not_equal(err, -EBUSY, "arbitration lost in loopback mode");
	zassert_equal(err, 0, "failed to send frame (err %d)", err);
}

/**
 * @brief Add a CAN message queue with asserts.
 *
 * @param dev    Pointer to the device structure for the driver instance.
 * @param filter CAN filter for the CAN message queue.
 *
 * @return CAN filter ID.
 */
static inline int add_rx_msgq(const struct device *dev, const struct can_filter *filter)
{
	int filter_id;

	filter_id = can_add_rx_filter_msgq(dev, &can_msgq, filter);
	zassert_not_equal(filter_id, -ENOSPC, "no filters available");
	zassert_true(filter_id >= 0, "negative filter number");

	return filter_id;
}

/**
 * @brief Add a CAN filter with asserts.
 *
 * @param dev      Pointer to the device structure for the driver instance.
 * @param filter   CAN filter.
 * @param callback Receive callback function.
 *
 * @return CAN filter ID.
 */
static inline int add_rx_filter(const struct device *dev,
				const struct can_filter *filter,
				can_rx_callback_t callback)
{
	int filter_id;

	k_sem_reset(&rx_callback_sem);

	filter_id = can_add_rx_filter(dev, callback, (void *)filter, filter);
	zassert_not_equal(filter_id, -ENOSPC, "no filters available");
	zassert_true(filter_id >= 0, "negative filter number");

	return filter_id;
}

/**
 * @brief Perform a send/receive test with a set of CAN ID filters and CAN frames.
 *
 * @param filter1 CAN filter 1
 * @param filter2 CAN filter 2
 * @param frame1  CAN frame 1
 * @param frame2  CAN frame 2
 */
static void send_receive(const struct can_filter *filter1,
			 const struct can_filter *filter2,
			 const struct can_frame *frame1,
			 const struct can_frame *frame2)
{
	struct can_frame frame_buffer;
	int filter_id_1;
	int filter_id_2;
	int err;

	filter_id_1 = add_rx_msgq(can_dev, filter1);
	send_test_frame(can_dev, frame1);

	err = k_msgq_get(&can_msgq, &frame_buffer, TEST_RECEIVE_TIMEOUT);
	zassert_equal(err, 0, "receive timeout");

	assert_frame_equal(&frame_buffer, frame1);
	can_remove_rx_filter(can_dev, filter_id_1);

	k_sem_reset(&tx_callback_sem);

	if (frame1->fd) {
		filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_fd_1);
	} else {
		filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1);
	}

	if (frame2->fd) {
		filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_fd_2);
	} else {
		filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2);
	}

	send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
	send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);

	err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT);
	zassert_equal(err, 0, "receive timeout");

	err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT);
	zassert_equal(err, 0, "receive timeout");

	err = k_sem_take(&tx_callback_sem, TEST_SEND_TIMEOUT);
	zassert_equal(err, 0, "missing TX callback");

	err = k_sem_take(&tx_callback_sem, TEST_SEND_TIMEOUT);
	zassert_equal(err, 0, "missing TX callback");

	can_remove_rx_filter(can_dev, filter_id_1);
	can_remove_rx_filter(can_dev, filter_id_2);
}

/**
 * @brief Test getting the CAN controller capabilities.
 */
ZTEST(canfd, test_get_capabilities)
{
	can_mode_t cap;
	int err;

	err = can_get_capabilities(can_dev, &cap);
	zassert_equal(err, 0, "failed to get CAN capabilities (err %d)", err);
	zassert_not_equal(cap & (CAN_MODE_LOOPBACK | CAN_MODE_FD), 0,
			  "CAN-FD loopback mode not supported");
}

/**
 * @brief Test send/receive with standard (11-bit) CAN IDs and classic CAN frames.
 */
ZTEST(canfd, test_send_receive_classic)
{
	send_receive(&test_std_filter_1, &test_std_filter_2,
		     &test_std_frame_1, &test_std_frame_2);
}

/**
 * @brief Test send/receive with standard (11-bit) CAN IDs and CAN-FD frames.
 */
ZTEST(canfd, test_send_receive_fd)
{
	send_receive(&test_std_filter_1, &test_std_filter_2,
		     &test_std_frame_fd_1, &test_std_frame_fd_2);
}

/**
 * @brief Test send/receive with (11-bit) CAN IDs, mixed classic and CAN-FD frames.
 */
ZTEST(canfd, test_send_receive_mixed)
{
	send_receive(&test_std_filter_1, &test_std_filter_2,
		     &test_std_frame_fd_1, &test_std_frame_2);
}

/**
 * @brief Test setting bitrate is not allowed while started.
 */
ZTEST_USER(canfd, test_set_bitrate_data_while_started)
{
	int err;

	err = can_set_bitrate_data(can_dev, TEST_BITRATE);
	zassert_not_equal(err, 0, "changed data bitrate while started");
	zassert_equal(err, -EBUSY, "wrong error return code (err %d)", err);
}

/**
 * @brief Test setting timing is not allowed while started.
 */
ZTEST_USER(canfd, test_set_timing_data_while_started)
{
	struct can_timing timing;
	int err;

	timing.sjw = CAN_SJW_NO_CHANGE;

	err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE, TEST_SAMPLE_POINT);
	zassert_ok(err, "failed to calculate data timing (err %d)", err);

	err = can_set_timing(can_dev, &timing);
	zassert_not_equal(err, 0, "changed data timing while started");
	zassert_equal(err, -EBUSY, "wrong error return code (err %d)", err);
}

void *canfd_setup(void)
{
	int err;

	k_sem_init(&rx_callback_sem, 0, 2);
	k_sem_init(&tx_callback_sem, 0, 2);

	zassert_true(device_is_ready(can_dev), "CAN device not ready");

	err = can_set_mode(can_dev, CAN_MODE_LOOPBACK | CAN_MODE_FD);
	zassert_equal(err, 0, "failed to set CAN-FD loopback mode (err %d)", err);

	err = can_start(can_dev);
	zassert_equal(err, 0, "failed to start CAN controller (err %d)", err);

	return NULL;
}

ZTEST_SUITE(canfd, NULL, canfd_setup, NULL, NULL, NULL);
