/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
#define _GNU_SOURCE
#include "array.h"
#include "container-of.h"
#include "transport.h"
#include "test.h"

#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct pldm_transport_test {
	struct pldm_transport transport;
	const struct pldm_transport_test_descriptor *seq;
	size_t count;
	size_t cursor;
	int timerfd;
};

#define transport_to_test(ptr)                                                 \
	container_of(ptr, struct pldm_transport_test, transport)

LIBPLDM_ABI_TESTING
struct pldm_transport *pldm_transport_test_core(struct pldm_transport_test *ctx)
{
	return &ctx->transport;
}

#ifdef PLDM_HAS_POLL
#include <poll.h>
LIBPLDM_ABI_TESTING
int pldm_transport_test_init_pollfd(struct pldm_transport *ctx,
				    struct pollfd *pollfd)
{
	static const struct itimerspec disable = {
		.it_value = { 0, 0 },
		.it_interval = { 0, 0 },
	};
	struct pldm_transport_test *test = transport_to_test(ctx);
	const struct pldm_transport_test_descriptor *desc;
	int rc;

	rc = timerfd_settime(test->timerfd, 0, &disable, NULL);
	if (rc < 0) {
		return PLDM_REQUESTER_POLL_FAIL;
	}

	if (test->cursor >= test->count) {
		return PLDM_REQUESTER_POLL_FAIL;
	}

	desc = &test->seq[test->cursor];

	if (desc->type == PLDM_TRANSPORT_TEST_ELEMENT_LATENCY) {
		rc = timerfd_settime(test->timerfd, 0, &desc->latency, NULL);
		if (rc < 0) {
			return PLDM_REQUESTER_POLL_FAIL;
		}

		/* This was an explicit latency element, so now move beyond it for recv */
		test->cursor++;
	} else if (desc->type == PLDM_TRANSPORT_TEST_ELEMENT_MSG_RECV) {
		/* Expire the timer immediately so it appears ready */
		static const struct timespec ensure_ready = {
			.tv_sec = 0,
			.tv_nsec = 2,
		};
		static const struct itimerspec ready = {
			.it_value = { 0, 1 },
			.it_interval = { 0, 0 },
		};
		struct pollfd pfds[] = {
			{ .fd = test->timerfd, .events = POLLIN },
		};

		rc = timerfd_settime(test->timerfd, 0, &ready, NULL);
		if (rc < 0) {
			return PLDM_REQUESTER_POLL_FAIL;
		}

		rc = ppoll(pfds, ARRAY_SIZE(pfds), &ensure_ready, NULL);
		if (rc < 1) {
			return PLDM_REQUESTER_POLL_FAIL;
		}

		/* Don't increment test->cursor as recv needs to consume the current test element */
	} else {
		return PLDM_REQUESTER_POLL_FAIL;
	}

	pollfd->fd = test->timerfd;
	pollfd->events = POLLIN;

	return 0;
}
#endif

static pldm_requester_rc_t pldm_transport_test_recv(struct pldm_transport *ctx,
						    pldm_tid_t *tid,
						    void **pldm_resp_msg,
						    size_t *resp_msg_len)
{
	struct pldm_transport_test *test = transport_to_test(ctx);
	const struct pldm_transport_test_descriptor *desc;
	void *msg;

	if (test->cursor >= test->count) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	desc = &test->seq[test->cursor];

	if (desc->type != PLDM_TRANSPORT_TEST_ELEMENT_MSG_RECV) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	msg = malloc(desc->recv_msg.len);
	if (!msg) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	memcpy(msg, desc->recv_msg.msg, desc->recv_msg.len);
	*pldm_resp_msg = msg;
	*resp_msg_len = desc->recv_msg.len;
	*tid = desc->recv_msg.src;

	test->cursor++;

	return PLDM_REQUESTER_SUCCESS;
}

static pldm_requester_rc_t pldm_transport_test_send(struct pldm_transport *ctx,
						    pldm_tid_t tid,
						    const void *pldm_req_msg,
						    size_t req_msg_len)
{
	struct pldm_transport_test *test = transport_to_test(ctx);
	const struct pldm_transport_test_descriptor *desc;

	if (test->cursor > test->count) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	desc = &test->seq[test->cursor];

	if (desc->type != PLDM_TRANSPORT_TEST_ELEMENT_MSG_SEND) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	if (desc->send_msg.dst != tid) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	if (desc->send_msg.len != req_msg_len) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	if (memcmp(desc->send_msg.msg, pldm_req_msg, req_msg_len) != 0) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	test->cursor++;

	return PLDM_REQUESTER_SUCCESS;
}

LIBPLDM_ABI_TESTING
int pldm_transport_test_init(struct pldm_transport_test **ctx,
			     const struct pldm_transport_test_descriptor *seq,
			     size_t count)
{
	int rc;

	if (!ctx || *ctx) {
		return -EINVAL;
	}

	struct pldm_transport_test *test = malloc(sizeof(*test));
	if (!test) {
		return -ENOMEM;
	}

	test->transport.name = "TEST";
	test->transport.version = 1;
	test->transport.recv = pldm_transport_test_recv;
	test->transport.send = pldm_transport_test_send;
	test->transport.init_pollfd = pldm_transport_test_init_pollfd;
	test->seq = seq;
	test->count = count;
	test->cursor = 0;
	test->timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
	if (test->timerfd < 0) {
		rc = -errno;
		goto cleanup_test;
	}

	*ctx = test;

	return 0;

cleanup_test:
	free(test);
	return rc;
}

LIBPLDM_ABI_TESTING
void pldm_transport_test_destroy(struct pldm_transport_test *ctx)
{
	close(ctx->timerfd);
	free(ctx);
}
