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

#ifdef NDEBUG
#undef NDEBUG
#endif

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

#include <libmctp.h>
#include <libmctp-alloc.h>

#include "test-utils.h"

struct mctp_binding_bridge {
	struct mctp_binding binding;
	int rx_count;
	int tx_count;
	uint8_t last_pkt_data;
	uint8_t tx_storage[MCTP_PKTBUF_SIZE(MCTP_BTU)];
};

struct test_ctx {
	struct mctp *mctp;
	struct mctp_binding_bridge *bindings[2];
};

static int mctp_binding_bridge_tx(struct mctp_binding *b,
				  struct mctp_pktbuf *pkt)
{
	struct mctp_binding_bridge *binding =
		container_of(b, struct mctp_binding_bridge, binding);

	binding->tx_count++;
	assert(mctp_pktbuf_size(pkt) == sizeof(struct mctp_hdr) + 1);
	binding->last_pkt_data = *(uint8_t *)mctp_pktbuf_data(pkt);

	return 0;
}

static void mctp_binding_bridge_rx(struct mctp_binding_bridge *binding,
				   uint8_t key)
{
	struct mctp_pktbuf *pkt;
	struct mctp_hdr *hdr;
	uint8_t *buf;

	pkt = mctp_pktbuf_alloc(&binding->binding, sizeof(struct mctp_hdr) + 1);
	assert(pkt);

	hdr = mctp_pktbuf_hdr(pkt);
	hdr->flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM;

	/* arbitrary src/dest, as we're bridging */
	hdr->src = 1;
	hdr->dest = 2;

	buf = mctp_pktbuf_data(pkt);
	*buf = key;

	binding->rx_count++;
	mctp_bus_rx(&binding->binding, pkt);
	mctp_pktbuf_free(pkt);
}

static struct mctp_binding_bridge *mctp_binding_bridge_init(char *name)
{
	struct mctp_binding_bridge *binding;

	binding = __mctp_alloc(sizeof(*binding));
	memset(binding, 0, sizeof(*binding));
	binding->binding.name = name;
	binding->binding.version = 1;
	binding->binding.tx = mctp_binding_bridge_tx;
	binding->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
	binding->binding.pkt_header = 0;
	binding->binding.pkt_trailer = 0;
	binding->binding.tx_storage = binding->tx_storage;
	return binding;
}

int main(void)
{
	struct test_ctx _ctx, *ctx = &_ctx;
	ctx->mctp = mctp_init();

	ctx->bindings[0] = mctp_binding_bridge_init("binding0");
	ctx->bindings[1] = mctp_binding_bridge_init("binding1");
	mctp_bridge_busses(ctx->mctp, &ctx->bindings[0]->binding,
			   &ctx->bindings[1]->binding);

	mctp_binding_set_tx_enabled(&ctx->bindings[0]->binding, true);
	mctp_binding_set_tx_enabled(&ctx->bindings[1]->binding, true);

	mctp_binding_bridge_rx(ctx->bindings[0], 0xaa);
	assert(ctx->bindings[0]->tx_count == 0);
	assert(ctx->bindings[1]->tx_count == 1);
	assert(ctx->bindings[1]->last_pkt_data == 0xaa);

	mctp_binding_bridge_rx(ctx->bindings[1], 0x55);
	assert(ctx->bindings[1]->tx_count == 1);
	assert(ctx->bindings[0]->tx_count == 1);
	assert(ctx->bindings[0]->last_pkt_data == 0x55);

	__mctp_free(ctx->bindings[1]);
	__mctp_free(ctx->bindings[0]);
	mctp_destroy(ctx->mctp);

	return EXIT_SUCCESS;
}
