#include "mctp-defines.h"
#include "base.h"
#include "container-of.h"
#include "libpldm/pldm.h"
#include "libpldm/transport.h"
#include "socket.h"
#include "transport.h"

#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#define MCTP_DEMUX_NAME "libmctp-demux-daemon"
const uint8_t mctp_msg_type = MCTP_MSG_TYPE_PLDM;

struct pldm_transport_mctp_demux {
	struct pldm_transport transport;
	int socket;
	/* In the future this probably needs to move to a tid-eid-uuid/network
	 * id mapping for multi mctp networks */
	pldm_tid_t tid_eid_map[MCTP_MAX_NUM_EID];
	struct pldm_socket_sndbuf socket_send_buf;
};

#define transport_to_demux(ptr)                                                \
	container_of(ptr, struct pldm_transport_mctp_demux, transport)

LIBPLDM_ABI_TESTING
struct pldm_transport *
pldm_transport_mctp_demux_core(struct pldm_transport_mctp_demux *ctx)
{
	return &ctx->transport;
}

static pldm_requester_rc_t pldm_transport_mctp_demux_open(void)
{
	int fd = -1;
	ssize_t rc = -1;

	fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
	if (fd == -1) {
		return fd;
	}

	const char path[] = "\0mctp-mux";
	struct sockaddr_un addr;
	addr.sun_family = AF_UNIX;
	memcpy(addr.sun_path, path, sizeof(path) - 1);
	rc = connect(fd, (struct sockaddr *)&addr,
		     sizeof(path) + sizeof(addr.sun_family) - 1);
	if (rc == -1) {
		return PLDM_REQUESTER_OPEN_FAIL;
	}
	rc = write(fd, &mctp_msg_type, sizeof(mctp_msg_type));
	if (rc == -1) {
		return PLDM_REQUESTER_OPEN_FAIL;
	}

	return fd;
}

LIBPLDM_ABI_TESTING
int pldm_transport_mctp_demux_init_pollfd(struct pldm_transport *t,
					  struct pollfd *pollfd)
{
	struct pldm_transport_mctp_demux *ctx = transport_to_demux(t);
	pollfd->fd = ctx->socket;
	pollfd->events = POLLIN;
	return 0;
}

static int
pldm_transport_mctp_demux_get_eid(struct pldm_transport_mctp_demux *ctx,
				  pldm_tid_t tid, mctp_eid_t *eid)
{
	int i;
	for (i = 0; i < MCTP_MAX_NUM_EID; i++) {
		if (ctx->tid_eid_map[i] == tid) {
			*eid = i;
			return 0;
		}
	}
	*eid = -1;
	return -1;
}

LIBPLDM_ABI_TESTING
int pldm_transport_mctp_demux_map_tid(struct pldm_transport_mctp_demux *ctx,
				      pldm_tid_t tid, mctp_eid_t eid)
{
	ctx->tid_eid_map[eid] = tid;

	return 0;
}

LIBPLDM_ABI_TESTING
int pldm_transport_mctp_demux_unmap_tid(struct pldm_transport_mctp_demux *ctx,
					__attribute__((unused)) pldm_tid_t tid,
					mctp_eid_t eid)
{
	ctx->tid_eid_map[eid] = 0;

	return 0;
}

static pldm_requester_rc_t
pldm_transport_mctp_demux_recv(struct pldm_transport *t, pldm_tid_t tid,
			       void **pldm_resp_msg, size_t *resp_msg_len)
{
	struct pldm_transport_mctp_demux *demux = transport_to_demux(t);
	mctp_eid_t eid = 0;
	int rc = pldm_transport_mctp_demux_get_eid(demux, tid, &eid);
	if (rc) {
		return PLDM_REQUESTER_RECV_FAIL;
	}

	ssize_t min_len = sizeof(eid) + sizeof(mctp_msg_type) +
			  sizeof(struct pldm_msg_hdr);
	ssize_t length = recv(demux->socket, NULL, 0, MSG_PEEK | MSG_TRUNC);
	if (length <= 0) {
		return PLDM_REQUESTER_RECV_FAIL;
	}
	uint8_t *buf = malloc(length);
	if (buf == NULL) {
		return PLDM_REQUESTER_RECV_FAIL;
	}
	if (length < min_len) {
		/* read and discard */
		recv(demux->socket, buf, length, 0);
		free(buf);
		return PLDM_REQUESTER_INVALID_RECV_LEN;
	}
	struct iovec iov[2];
	uint8_t mctp_prefix[2];
	size_t mctp_prefix_len = 2;
	size_t pldm_len = length - mctp_prefix_len;
	iov[0].iov_len = mctp_prefix_len;
	iov[0].iov_base = mctp_prefix;
	iov[1].iov_len = pldm_len;
	iov[1].iov_base = buf;
	struct msghdr msg = { 0 };
	msg.msg_iov = iov;
	msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]);
	ssize_t bytes = recvmsg(demux->socket, &msg, 0);
	if (length != bytes) {
		free(buf);
		return PLDM_REQUESTER_INVALID_RECV_LEN;
	}
	if ((mctp_prefix[0] != eid) || (mctp_prefix[1] != mctp_msg_type)) {
		free(buf);
		return PLDM_REQUESTER_NOT_PLDM_MSG;
	}
	*pldm_resp_msg = buf;
	*resp_msg_len = pldm_len;
	return PLDM_REQUESTER_SUCCESS;
}

static pldm_requester_rc_t
pldm_transport_mctp_demux_send(struct pldm_transport *t, pldm_tid_t tid,
			       const void *pldm_req_msg, size_t req_msg_len)
{
	struct pldm_transport_mctp_demux *demux = transport_to_demux(t);
	mctp_eid_t eid = 0;
	if (pldm_transport_mctp_demux_get_eid(demux, tid, &eid)) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	uint8_t hdr[2] = { eid, mctp_msg_type };

	struct iovec iov[2];
	iov[0].iov_base = hdr;
	iov[0].iov_len = sizeof(hdr);
	iov[1].iov_base = (uint8_t *)pldm_req_msg;
	iov[1].iov_len = req_msg_len;

	struct msghdr msg = { 0 };
	msg.msg_iov = iov;
	msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]);

	if (req_msg_len > INT_MAX ||
	    pldm_socket_sndbuf_accomodate(&(demux->socket_send_buf),
					  (int)req_msg_len)) {
		return PLDM_REQUESTER_SEND_FAIL;
	}

	ssize_t rc = sendmsg(demux->socket, &msg, 0);
	if (rc == -1) {
		return PLDM_REQUESTER_SEND_FAIL;
	}
	return PLDM_REQUESTER_SUCCESS;
}

LIBPLDM_ABI_TESTING
int pldm_transport_mctp_demux_init(struct pldm_transport_mctp_demux **ctx)
{
	if (!ctx || *ctx) {
		return -EINVAL;
	}

	struct pldm_transport_mctp_demux *demux =
		calloc(1, sizeof(struct pldm_transport_mctp_demux));
	if (!demux) {
		return -ENOMEM;
	}

	demux->transport.name = MCTP_DEMUX_NAME;
	demux->transport.version = 1;
	demux->transport.recv = pldm_transport_mctp_demux_recv;
	demux->transport.send = pldm_transport_mctp_demux_send;
	demux->transport.init_pollfd = pldm_transport_mctp_demux_init_pollfd;
	demux->socket = pldm_transport_mctp_demux_open();
	if (demux->socket == -1) {
		free(demux);
		return -1;
	}

	if (pldm_socket_sndbuf_init(&demux->socket_send_buf, demux->socket)) {
		close(demux->socket);
		free(demux);
		return -1;
	}

	*ctx = demux;
	return 0;
}

LIBPLDM_ABI_TESTING
void pldm_transport_mctp_demux_destroy(struct pldm_transport_mctp_demux *ctx)
{
	if (!ctx) {
		return;
	}
	close(ctx->socket);
	free(ctx);
}

/* Temporary for old API */
LIBPLDM_ABI_TESTING
struct pldm_transport_mctp_demux *
pldm_transport_mctp_demux_init_with_fd(int mctp_fd)
{
	struct pldm_transport_mctp_demux *demux =
		calloc(1, sizeof(struct pldm_transport_mctp_demux));
	if (!demux) {
		return NULL;
	}

	demux->transport.name = MCTP_DEMUX_NAME;
	demux->transport.version = 1;
	demux->transport.recv = pldm_transport_mctp_demux_recv;
	demux->transport.send = pldm_transport_mctp_demux_send;
	demux->transport.init_pollfd = pldm_transport_mctp_demux_init_pollfd;
	/* dup is so we can call pldm_transport_mctp_demux_destroy which closes
	 * the socket, without closing the fd that is being used by the consumer
	 */
	demux->socket = dup(mctp_fd);
	if (demux->socket == -1) {
		free(demux);
		return NULL;
	}

	if (pldm_socket_sndbuf_init(&demux->socket_send_buf, demux->socket)) {
		close(demux->socket);
		free(demux);
		return NULL;
	}

	return demux;
}

LIBPLDM_ABI_TESTING
int pldm_transport_mctp_demux_get_socket_fd(
	struct pldm_transport_mctp_demux *ctx)
{
	if (ctx && ctx->socket) {
		return ctx->socket;
	}
	return -1;
}
