/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <libmctp.h>

#include "test-utils.h"

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

struct test_ctx {
	struct mctp			*mctp;
	struct mctp_binding_test	*binding;
	int				rx_count;
	uint8_t				rx_data[4];
	size_t				rx_len;
};

static void test_rx(uint8_t eid, void *data, void *msg, size_t len)
{
	struct test_ctx *ctx = data;

	(void)eid;

	ctx->rx_count++;

	/* append incoming message data to the existing rx_data */
	assert(len <= sizeof(ctx->rx_data));
	assert(ctx->rx_len + len <= sizeof(ctx->rx_data));

	memcpy(ctx->rx_data + ctx->rx_len, msg, len);
	ctx->rx_len += len;
}

#define SEQ(x) (x << MCTP_HDR_SEQ_SHIFT)

struct test {
	int		n_packets;
	uint8_t		flags_seq_tags[4];
	int		exp_rx_count;
	size_t		exp_rx_len;
} tests[] = {
	{
		/* single packet */
		.n_packets = 1,
		.flags_seq_tags = {
			SEQ(1) | MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM,
		},
		.exp_rx_count = 1,
		.exp_rx_len = 1,
	},
	{
		/* two packets: one start, one end */
		.n_packets = 2,
		.flags_seq_tags = {
			SEQ(1) | MCTP_HDR_FLAG_SOM,
			SEQ(2) | MCTP_HDR_FLAG_EOM,
		},
		.exp_rx_count = 1,
		.exp_rx_len = 2,
	},
	{
		/* three packets: one start, one no flags, one end */
		.n_packets = 3,
		.flags_seq_tags = {
			SEQ(1) | MCTP_HDR_FLAG_SOM,
			SEQ(2),
			SEQ(3) | MCTP_HDR_FLAG_EOM,
		},
		.exp_rx_count = 1,
		.exp_rx_len = 3,
	},
	{
		/* two packets, wrapping sequence numbers */
		.n_packets = 2,
		.flags_seq_tags = {
			SEQ(3) | MCTP_HDR_FLAG_SOM,
			SEQ(0) | MCTP_HDR_FLAG_EOM,
		},
		.exp_rx_count = 1,
		.exp_rx_len = 2,
	},
	{
		/* two packets, invalid sequence number */
		.n_packets = 2,
		.flags_seq_tags = {
			SEQ(1) | MCTP_HDR_FLAG_SOM,
			SEQ(3) | MCTP_HDR_FLAG_EOM,
		},
		.exp_rx_count = 0,
		.exp_rx_len = 0,
	},
};

static void run_one_test(struct test_ctx *ctx, struct test *test)
{
	const mctp_eid_t local_eid = 8;
	const mctp_eid_t remote_eid = 9;
	struct {
		struct mctp_hdr	hdr;
		uint8_t		payload[1];
	} pktbuf;
	int i;

	ctx->rx_count = 0;
	ctx->rx_len = 0;

	mctp_test_stack_init(&ctx->mctp, &ctx->binding, local_eid);

	mctp_set_rx_all(ctx->mctp, test_rx, ctx);

	for (i = 0; i < test->n_packets; i++) {
		memset(&pktbuf, 0, sizeof(pktbuf));
		pktbuf.hdr.dest = local_eid;
		pktbuf.hdr.src = remote_eid;
		pktbuf.hdr.flags_seq_tag = test->flags_seq_tags[i];
		pktbuf.payload[0] = i;

		mctp_binding_test_rx_raw(ctx->binding,
				&pktbuf, sizeof(pktbuf));
	}

	assert(ctx->rx_count == test->exp_rx_count);
	assert(ctx->rx_len == test->exp_rx_len);

	/* ensure the payload data was reconstructed correctly */
	for (i = 0; i < (int)ctx->rx_len; i++)
		assert(ctx->rx_data[i] == i);
}


int main(void)
{
	struct test_ctx ctx;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(tests); i++)
		run_one_test(&ctx, &tests[i]);

	return EXIT_SUCCESS;
}
