/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#include <libpldm/base.h>
#include <libpldm/requester/pldm.h>
#include <libpldm/transport.h>

#include <bits/types/struct_iovec.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

/* Temporary for old api */
#include "libpldm/transport/mctp-demux.h"
extern int
pldm_transport_mctp_demux_get_socket_fd(struct pldm_transport_mctp_demux *ctx);
extern struct pldm_transport_mctp_demux *
pldm_transport_mctp_demux_init_with_fd(int mctp_fd);

/* ---  old APIS written in terms of the new API -- */
/*
 * pldm_open returns the file descriptor to the MCTP socket, which needs to
 * persist over api calls (so a consumer can poll it for incoming messages).
 * So we need a global variable to store the transport struct
 */
static struct pldm_transport_mctp_demux *open_transport;

LIBPLDM_ABI_DEPRECATED
pldm_requester_rc_t pldm_open(void)
{
	int fd = PLDM_REQUESTER_OPEN_FAIL;

	if (open_transport) {
		fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);

		/* If someone has externally issued close() on fd then we need to start again. Use
		 * `fcntl(..., F_GETFD)` to test whether fd is valid. */
		if (fd < 0 || fcntl(fd, F_GETFD) < 0) {
			pldm_close();
		}
	}

	/* We retest open_transport as it may have been set to NULL by pldm_close() above. */
	if (!open_transport) {
		struct pldm_transport_mctp_demux *demux = NULL;

		if (pldm_transport_mctp_demux_init(&demux) < 0) {
			return PLDM_REQUESTER_OPEN_FAIL;
		}

		open_transport = demux;

		fd = pldm_transport_mctp_demux_get_socket_fd(open_transport);
	}

	return fd;
}

/* This macro does the setup and teardown required for the old API to use the
 * new API. Since the setup/teardown logic is the same for all four send/recv
 * functions, it makes sense to only define it once. */
#define PLDM_REQ_FN(eid, fd, fn, rc, ...)                                        \
	do {                                                                     \
		struct pldm_transport_mctp_demux *demux;                         \
		bool using_open_transport = false;                               \
		pldm_tid_t tid = eid;                                            \
		struct pldm_transport *ctx;                                      \
		/* The fd can be for a socket we opened or one the consumer    \
		 * opened. */ \
		if (open_transport &&                                            \
		    mctp_fd == pldm_transport_mctp_demux_get_socket_fd(          \
				       open_transport)) {                        \
			using_open_transport = true;                             \
			demux = open_transport;                                  \
		} else {                                                         \
			demux = pldm_transport_mctp_demux_init_with_fd(fd);      \
			if (!demux) {                                            \
				rc = PLDM_REQUESTER_OPEN_FAIL;                   \
				goto transport_out;                              \
			}                                                        \
		}                                                                \
		ctx = pldm_transport_mctp_demux_core(demux);                     \
		rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid);         \
		if (rc) {                                                        \
			rc = PLDM_REQUESTER_OPEN_FAIL;                           \
			goto transport_out;                                      \
		}                                                                \
		rc = fn(ctx, tid, __VA_ARGS__);                                  \
	transport_out:                                                           \
		if (!using_open_transport) {                                     \
			pldm_transport_mctp_demux_destroy(demux);                \
		}                                                                \
		break;                                                           \
	} while (0)

LIBPLDM_ABI_DEPRECATED
pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
				  uint8_t **pldm_resp_msg, size_t *resp_msg_len)
{
	pldm_requester_rc_t rc = 0;

	struct pldm_transport_mctp_demux *demux;
	bool using_open_transport = false;
	pldm_tid_t tid = eid;
	struct pldm_transport *ctx;
	/* The fd can be for a socket we opened or one the consumer
	 * opened. */
	if (open_transport &&
	    mctp_fd ==
		    pldm_transport_mctp_demux_get_socket_fd(open_transport)) {
		using_open_transport = true;
		demux = open_transport;
	} else {
		demux = pldm_transport_mctp_demux_init_with_fd(mctp_fd);
		if (!demux) {
			rc = PLDM_REQUESTER_OPEN_FAIL;
			goto transport_out;
		}
	}
	ctx = pldm_transport_mctp_demux_core(demux);
	rc = pldm_transport_mctp_demux_map_tid(demux, tid, eid);
	if (rc) {
		rc = PLDM_REQUESTER_OPEN_FAIL;
		goto transport_out;
	}
	/* TODO this is the only change, can we work this into the macro? */
	rc = pldm_transport_recv_msg(ctx, &tid, (void **)pldm_resp_msg,
				     resp_msg_len);

	struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
	if (rc != PLDM_REQUESTER_SUCCESS) {
		return rc;
	}
	if (hdr && (hdr->request || hdr->datagram)) {
		free(*pldm_resp_msg);
		*pldm_resp_msg = NULL;
		return PLDM_REQUESTER_NOT_RESP_MSG;
	}
	uint8_t pldm_cc = 0;
	if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_cc))) {
		free(*pldm_resp_msg);
		*pldm_resp_msg = NULL;
		return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
	}

transport_out:
	if (!using_open_transport) {
		pldm_transport_mctp_demux_destroy(demux);
	}

	return rc;
}

LIBPLDM_ABI_DEPRECATED
pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd,
			      __attribute__((unused)) uint8_t instance_id,
			      uint8_t **pldm_resp_msg, size_t *resp_msg_len)
{
	pldm_requester_rc_t rc =
		pldm_recv_any(eid, mctp_fd, pldm_resp_msg, resp_msg_len);
	struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
	if (rc == PLDM_REQUESTER_SUCCESS && hdr &&
	    hdr->instance_id != instance_id) {
		free(*pldm_resp_msg);
		*pldm_resp_msg = NULL;
		return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
	}
	return rc;
}

LIBPLDM_ABI_DEPRECATED
pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
				   const uint8_t *pldm_req_msg,
				   size_t req_msg_len, uint8_t **pldm_resp_msg,
				   size_t *resp_msg_len)
{
	pldm_requester_rc_t rc = 0;
	struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
	if (hdr && !hdr->request) {
		return PLDM_REQUESTER_NOT_REQ_MSG;
	}
	PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_recv_msg, rc,
		    pldm_req_msg, req_msg_len, (void **)pldm_resp_msg,
		    resp_msg_len);
	if (rc != PLDM_REQUESTER_SUCCESS) {
		return rc;
	}
	hdr = (struct pldm_msg_hdr *)(*pldm_resp_msg);
	if (hdr && (hdr->request || hdr->datagram)) {
		free(*pldm_resp_msg);
		*pldm_resp_msg = NULL;
		return PLDM_REQUESTER_NOT_RESP_MSG;
	}
	return rc;
}

LIBPLDM_ABI_DEPRECATED
pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
			      const uint8_t *pldm_req_msg, size_t req_msg_len)
{
	pldm_requester_rc_t rc = 0;
	struct pldm_msg_hdr *hdr = (struct pldm_msg_hdr *)pldm_req_msg;
	if (!hdr->request) {
		return PLDM_REQUESTER_NOT_REQ_MSG;
	}
	PLDM_REQ_FN(eid, mctp_fd, pldm_transport_send_msg, rc,
		    (void *)pldm_req_msg, req_msg_len);
	return rc;
}

/* Adding this here for completeness in the case we can't smoothly
 * transition apps over to the new api */
LIBPLDM_ABI_DEPRECATED
void pldm_close(void)
{
	if (open_transport) {
		pldm_transport_mctp_demux_destroy(open_transport);
	}
	open_transport = NULL;
}
