/*
 * 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>

#include "common.h"

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

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, 0);
	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, 0);
	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_fdf_frame_1, 0);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_fdf_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_fdf_frame_2, 0);
	zassert_equal(dev, can_dev, "CAN device does not match");
	zassert_equal_ptr(filter, &test_std_fdf_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, 0);
	can_remove_rx_filter(can_dev, filter_id_1);

	k_sem_reset(&tx_callback_sem);

	if ((frame1->flags & CAN_FRAME_FDF) != 0) {
		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->flags & CAN_FRAME_FDF) != 0) {
		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_fdf_filter_1, &test_std_fdf_filter_2,
		     &test_std_fdf_frame_1, &test_std_fdf_frame_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_fdf_filter_1, &test_std_filter_2,
		     &test_std_fdf_frame_1, &test_std_frame_2);
}

/**
 * @brief Test that CAN RX filters are preserved through CAN controller mode changes.
 */
static void check_filters_preserved_between_modes(can_mode_t first, can_mode_t second)
{
	struct can_frame frame;
	enum can_state state;
	int filter_id_1;
	int filter_id_2;
	int err;

	/* Stop controller and set first mode */
	err = can_stop(can_dev);
	zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);

	err = can_get_state(can_dev, &state, NULL);
	zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
	zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");

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

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

	/* Add classic CAN and CAN-FD filter */
	filter_id_1 = add_rx_msgq(can_dev, &test_std_filter_1);
	filter_id_2 = add_rx_msgq(can_dev, &test_std_fdf_filter_2);

	/* Verify classic filter in first mode */
	send_test_frame(can_dev, &test_std_frame_1);
	err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
	zassert_equal(err, 0, "receive timeout");
	assert_frame_equal(&frame, &test_std_frame_1, 0);

	if ((first & CAN_MODE_FD) != 0) {
		/* Verify CAN-FD filter in first mode */
		send_test_frame(can_dev, &test_std_fdf_frame_2);
		err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
		zassert_equal(err, 0, "receive timeout");
		assert_frame_equal(&frame, &test_std_fdf_frame_2, 0);
	}

	/* Stop controller and set second mode */
	err = can_stop(can_dev);
	zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);

	err = can_get_state(can_dev, &state, NULL);
	zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
	zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");

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

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

	/* Verify classic filter in second mode */
	send_test_frame(can_dev, &test_std_frame_1);
	err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
	zassert_equal(err, 0, "receive timeout");
	assert_frame_equal(&frame, &test_std_frame_1, 0);

	if ((second & CAN_MODE_FD) != 0) {
		/* Verify CAN-FD filter in second mode */
		send_test_frame(can_dev, &test_std_fdf_frame_2);
		err = k_msgq_get(&can_msgq, &frame, TEST_RECEIVE_TIMEOUT);
		zassert_equal(err, 0, "receive timeout");
		assert_frame_equal(&frame, &test_std_fdf_frame_2, 0);
	}

	/* Stop controller and restore CAN-FD loopback mode */
	err = can_stop(can_dev);
	zassert_equal(err, 0, "failed to stop CAN controller (err %d)", err);

	err = can_get_state(can_dev, &state, NULL);
	zassert_equal(err, 0, "failed to get CAN state (err %d)", err);
	zassert_equal(state, CAN_STATE_STOPPED, "CAN controller not stopped");

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

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

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

/**
 * @brief Test that CAN RX filters are preserved through CAN controller mode changes between classic
 * CAN and CAN-FD.
 */
ZTEST_USER(canfd, test_filters_preserved_through_classic_to_fd_mode_change)
{
	check_filters_preserved_between_modes(CAN_MODE_NORMAL, CAN_MODE_FD);
}

/**
 * @brief Test that CAN RX filters are preserved through CAN controller mode changes between CAN-FD
 * and classic CAN.
 */
ZTEST_USER(canfd, test_filters_preserved_through_fd_to_classic_mode_change)
{
	check_filters_preserved_between_modes(CAN_MODE_FD, CAN_MODE_NORMAL);
}

/**
 * @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_3);
	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_3, 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);
}

static bool canfd_predicate(const void *state)
{
	can_mode_t cap;
	int err;

	ARG_UNUSED(state);

	if (!device_is_ready(can_dev)) {
		TC_PRINT("CAN device not ready");
		return false;
	}

	err = can_get_capabilities(can_dev, &cap);
	zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);

	if ((cap & CAN_MODE_FD) == 0) {
		return false;
	}

	return true;
}

void *canfd_setup(void)
{
	int err;

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

	(void)can_stop(can_dev);

	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, canfd_predicate, canfd_setup, NULL, NULL, NULL);
