/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <kernel.h>
#include <cmsis_os.h>

struct sample_data {
	int		data1;
	unsigned char	data2;
	unsigned int	data3;
};

#define MAIL1_DATA1	75663
#define MAIL1_DATA2	156
#define MAIL1_DATA3	1000001

#define MAIL2_DATA1	93567
#define MAIL2_DATA2	255
#define MAIL2_DATA3	1234567

#define TIMEOUT		500
#define Q_LEN		5

osMailQDef(mail, Q_LEN, struct sample_data);
osMailQId  mail_id;

void send_thread(void const *argument)
{
	int i;
	struct sample_data *tx_ptr;
	struct sample_data zeroblock;
	osStatus status;

	/* This is used for comparison later in the function */
	memset(&zeroblock, 0, sizeof(struct sample_data));

	status = osMailPut(mail_id, NULL);
	zassert_true(status == osErrorValue,
	 "Something's wrong with osMailPut. It is passing for NULL mail!");

	/* Wait for mail_recv to complete initial checks */
	osDelay(TIMEOUT);

	/* Prepare and send 1st mail */
	tx_ptr = osMailAlloc(mail_id, osWaitForever);
	zassert_true(tx_ptr != NULL, "Mail1 alloc failed");
	tx_ptr->data1 = MAIL1_DATA1;
	tx_ptr->data2 = MAIL1_DATA2;
	tx_ptr->data3 = MAIL1_DATA3;
	status = osMailPut(mail_id, tx_ptr);
	zassert_true(status == osOK, "osMailPut failure for mail1");

	/* Fill the queue with blocks of mails */
	for (i = 0; i < Q_LEN; i++) {

		/* Alternately use osMailAlloc and osMailCAlloc to ensure
		 * both the APIs are tested.
		 */
		if (i & 1) {
			tx_ptr = osMailCAlloc(mail_id, osWaitForever);
		} else {
			tx_ptr = osMailAlloc(mail_id, osWaitForever);
		}
		zassert_true(tx_ptr != NULL, "Mail alloc failed");

		tx_ptr->data1 = i;
		tx_ptr->data2 = i+1;
		tx_ptr->data3 = i+2;

		status = osMailPut(mail_id, tx_ptr);
		zassert_true(status == osOK,
				"osMailPut failure for mail!");
	}

	/* Try allocating mail to a full queue immediately
	 * before it is emptied out and assert failure
	 */
	tx_ptr = osMailAlloc(mail_id, 0);
	zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
	tx_ptr = osMailCAlloc(mail_id, 0);
	zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");

	/* Try allocating mail to a full queue within a duration
	 * less than TIMEOUT, before the queue is emptied out
	 */
	tx_ptr = osMailAlloc(mail_id, TIMEOUT/3);
	zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
	tx_ptr = osMailCAlloc(mail_id, TIMEOUT/3);
	zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");

	/* Send another mail after the queue is emptied */
	tx_ptr = osMailCAlloc(mail_id, TIMEOUT*2);
	zassert_true(tx_ptr != NULL, "Mail alloc failed");
	zassert_equal(memcmp(tx_ptr, &zeroblock, sizeof(struct sample_data)), 0,
		"osMailCAlloc returned memory not initialized to 0");

	tx_ptr->data1 = MAIL2_DATA1;
	tx_ptr->data2 = MAIL2_DATA2;
	tx_ptr->data3 = MAIL2_DATA3;
	status = osMailPut(mail_id, tx_ptr);
	zassert_true(status == osOK, "osMailPut failure for mail");
}

void mail_recv(void)
{
	int i;
	struct sample_data  *rx_ptr;
	osEvent  evt;
	osStatus status;

	/* Try getting mail immediately before the queue is populated */
	evt = osMailGet(mail_id, 0);
	zassert_true(evt.status == osOK,
			"Something's wrong with osMailGet!");

	/* Try receiving mail within a duration of TIMEOUT */
	evt = osMailGet(mail_id, TIMEOUT);
	zassert_true(evt.status == osEventTimeout,
		"Something's wrong with osMailGet!");

	/* Receive 1st mail */
	evt = osMailGet(mail_id, osWaitForever);
	zassert_true(evt.status == osEventMail, "osMailGet failure");

	rx_ptr = evt.value.p;
	zassert_equal(rx_ptr->data1, MAIL1_DATA1, NULL);
	zassert_equal(rx_ptr->data2, MAIL1_DATA2, NULL);
	zassert_equal(rx_ptr->data3, MAIL1_DATA3, NULL);

	status = osMailFree(mail_id, rx_ptr);
	zassert_true(status == osOK, "osMailFree failure");

	/* Wait for queue to get filled */
	osDelay(TIMEOUT);

	/* Empty the queue */
	for (i = 0; i < Q_LEN; i++) {
		evt = osMailGet(mail_id, osWaitForever);
		zassert_true(evt.status == osEventMail, "osMailGet failure");

		rx_ptr = evt.value.p;
		zassert_equal(rx_ptr->data1, i, NULL);
		zassert_equal(rx_ptr->data2, i + 1, NULL);
		zassert_equal(rx_ptr->data3, i + 2, NULL);

		status = osMailFree(mail_id, rx_ptr);
		zassert_true(status == osOK, "osMailFree failure");
	}

	/* Receive the next mail */
	evt = osMailGet(mail_id, osWaitForever);
	zassert_true(evt.status == osEventMail, "osMailGet failure");

	rx_ptr = evt.value.p;
	zassert_equal(rx_ptr->data1, MAIL2_DATA1, NULL);
	zassert_equal(rx_ptr->data2, MAIL2_DATA2, NULL);
	zassert_equal(rx_ptr->data3, MAIL2_DATA3, NULL);

	status = osMailFree(mail_id, rx_ptr);
	zassert_true(status == osOK, "osMailFree failure");
}

osThreadDef(send_thread, osPriorityNormal, 1, 0);

void test_mailq(void)
{
	osThreadId tid;

	mail_id = osMailCreate(osMailQ(mail), NULL);
	zassert_true(mail_id != NULL, "Mail creation failed");

	tid = osThreadCreate(osThread(send_thread), NULL);
	zassert_true(tid != NULL, "Thread creation failed");

	mail_recv();
}
