/* SPDX-License-Identifier: MIT */
/*
 * Description: test io_uring poll handling
 *
 */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <pthread.h>
#include <sys/epoll.h>

#include "liburing.h"

struct thread_data {
	struct io_uring *ring;
	int fd;
	int events;
	const char *test;
	int out[2];
};

static void *epoll_wait_fn(void *data)
{
	struct thread_data *td = data;
	struct epoll_event ev;

	if (epoll_wait(td->fd, &ev, 1, -1) < 0) {
		perror("epoll_wait");
		goto err;
	}

	return NULL;
err:
	return (void *) 1;
}

static void *iou_poll(void *data)
{
	struct thread_data *td = data;
	struct io_uring_sqe *sqe;
	struct io_uring_cqe *cqe;
	int ret;

	sqe = io_uring_get_sqe(td->ring);
	io_uring_prep_poll_add(sqe, td->fd, td->events);

	ret = io_uring_submit(td->ring);
	if (ret != 1) {
		fprintf(stderr, "submit got %d\n", ret);
		goto err;
	}

	ret = io_uring_wait_cqe(td->ring, &cqe);
	if (ret) {
		fprintf(stderr, "wait_cqe: %d\n", ret);
		goto err;
	}

	td->out[0] = cqe->res & 0x3f;
	io_uring_cqe_seen(td->ring, cqe);
	return NULL;
err:
	return (void *) 1;
}

static void *poll_pipe(void *data)
{
	struct thread_data *td = data;
	struct pollfd pfd;
	int ret;

	pfd.fd = td->fd;
	pfd.events = td->events;

	ret = poll(&pfd, 1, -1);
	if (ret < 0)
		perror("poll");

	td->out[1] = pfd.revents;
	return NULL;
}

static int do_pipe_pollin_test(struct io_uring *ring)
{
	struct thread_data td;
	pthread_t threads[2];
	int ret, pipe1[2];
	char buf;

	if (pipe(pipe1) < 0) {
		perror("pipe");
		return 1;
	}

	td.ring = ring;
	td.fd = pipe1[0];
	td.events = POLLIN;
	td.test = __FUNCTION__;

	pthread_create(&threads[1], NULL, iou_poll, &td);
	pthread_create(&threads[0], NULL, poll_pipe, &td);
	usleep(100000);

	buf = 0x89;
	ret = write(pipe1[1], &buf, sizeof(buf));
	if (ret != sizeof(buf)) {
		fprintf(stderr, "write failed: %d\n", ret);
		return 1;
	}

	pthread_join(threads[0], NULL);
	pthread_join(threads[1], NULL);

	if (td.out[0] != td.out[1]) {
		fprintf(stderr, "%s: res %x/%x differ\n", __FUNCTION__,
							td.out[0], td.out[1]);
		return 1;
	}
	return 0;
}

static int do_pipe_pollout_test(struct io_uring *ring)
{
	struct thread_data td;
	pthread_t threads[2];
	int ret, pipe1[2];
	char buf;

	if (pipe(pipe1) < 0) {
		perror("pipe");
		return 1;
	}

	td.ring = ring;
	td.fd = pipe1[1];
	td.events = POLLOUT;
	td.test = __FUNCTION__;

	pthread_create(&threads[0], NULL, poll_pipe, &td);
	pthread_create(&threads[1], NULL, iou_poll, &td);
	usleep(100000);

	buf = 0x89;
	ret = write(pipe1[1], &buf, sizeof(buf));
	if (ret != sizeof(buf)) {
		fprintf(stderr, "write failed: %d\n", ret);
		return 1;
	}

	pthread_join(threads[0], NULL);
	pthread_join(threads[1], NULL);

	if (td.out[0] != td.out[1]) {
		fprintf(stderr, "%s: res %x/%x differ\n", __FUNCTION__,
							td.out[0], td.out[1]);
		return 1;
	}

	return 0;
}

static int do_fd_test(struct io_uring *ring, const char *fname, int events)
{
	struct thread_data td;
	pthread_t threads[2];
	int fd;

	fd = open(fname, O_RDONLY);
	if (fd < 0) {
		perror("open");
		return 1;
	}

	td.ring = ring;
	td.fd = fd;
	td.events = events;
	td.test = __FUNCTION__;

	pthread_create(&threads[0], NULL, poll_pipe, &td);
	pthread_create(&threads[1], NULL, iou_poll, &td);

	pthread_join(threads[0], NULL);
	pthread_join(threads[1], NULL);

	if (td.out[0] != td.out[1]) {
		fprintf(stderr, "%s: res %x/%x differ\n", __FUNCTION__,
							td.out[0], td.out[1]);
		return 1;
	}

	return 0;
}

static int iou_epoll_ctl(struct io_uring *ring, int epfd, int fd,
			 struct epoll_event *ev)
{
	struct io_uring_sqe *sqe;
	struct io_uring_cqe *cqe;
	int ret;

	sqe = io_uring_get_sqe(ring);
	if (!sqe) {
		fprintf(stderr, "Failed to get sqe\n");
		return 1;
	}

	io_uring_prep_epoll_ctl(sqe, epfd, fd, EPOLL_CTL_ADD, ev);

	ret = io_uring_submit(ring);
	if (ret != 1) {
		fprintf(stderr, "submit: %d\n", ret);
		return 1;
	}

	ret = io_uring_wait_cqe(ring, &cqe);
	if (ret) {
		fprintf(stderr, "wait_cqe: %d\n", ret);
		return 1;
	}

	ret = cqe->res;
	io_uring_cqe_seen(ring, cqe);
	return ret;
}

static int do_test_epoll(struct io_uring *ring, int iou_epoll_add)
{
	struct epoll_event ev;
	struct thread_data td;
	pthread_t threads[2];
	int ret, pipe1[2];
	char buf;
	int fd;

	fd = epoll_create1(0);
	if (fd < 0) {
		perror("epoll_create");
		return 1;
	}

	if (pipe(pipe1) < 0) {
		perror("pipe");
		return 1;
	}

	ev.events = EPOLLIN;
	ev.data.fd = pipe1[0];

	if (!iou_epoll_add) {
		if (epoll_ctl(fd, EPOLL_CTL_ADD, pipe1[0], &ev) < 0) {
			perror("epoll_ctrl");
			return 1;
		}
	} else {
		ret = iou_epoll_ctl(ring, fd, pipe1[0], &ev);
		if (ret == -EINVAL) {
			fprintf(stdout, "epoll not supported, skipping\n");
			return 0;
		} else if (ret < 0) {
			return 1;
		}
	}

	td.ring = ring;
	td.fd = fd;
	td.events = POLLIN;
	td.test = __FUNCTION__;

	pthread_create(&threads[0], NULL, iou_poll, &td);
	pthread_create(&threads[1], NULL, epoll_wait_fn, &td);
	usleep(100000);

	buf = 0x89;
	ret = write(pipe1[1], &buf, sizeof(buf));
	if (ret != sizeof(buf)) {
		fprintf(stderr, "write failed: %d\n", ret);
		return 1;
	}

	pthread_join(threads[0], NULL);
	pthread_join(threads[1], NULL);
	return 0;
}

int main(int argc, char *argv[])
{
	struct io_uring ring;
	const char *fname;
	int ret;

	ret = io_uring_queue_init(1, &ring, 0);
	if (ret) {
		fprintf(stderr, "ring setup failed\n");
		return 1;
	}

	ret = do_pipe_pollin_test(&ring);
	if (ret) {
		fprintf(stderr, "pipe pollin test failed\n");
		return ret;
	}

	ret = do_pipe_pollout_test(&ring);
	if (ret) {
		fprintf(stderr, "pipe pollout test failed\n");
		return ret;
	}

	ret = do_test_epoll(&ring, 0);
	if (ret) {
		fprintf(stderr, "epoll test 0 failed\n");
		return ret;
	}

	ret = do_test_epoll(&ring, 1);
	if (ret) {
		fprintf(stderr, "epoll test 1 failed\n");
		return ret;
	}

	if (argc > 1)
		fname = argv[1];
	else
		fname = argv[0];

	ret = do_fd_test(&ring, fname, POLLIN);
	if (ret) {
		fprintf(stderr, "fd test IN failed\n");
		return ret;
	}

	ret = do_fd_test(&ring, fname, POLLOUT);
	if (ret) {
		fprintf(stderr, "fd test OUT failed\n");
		return ret;
	}

	ret = do_fd_test(&ring, fname, POLLOUT | POLLIN);
	if (ret) {
		fprintf(stderr, "fd test IN|OUT failed\n");
		return ret;
	}

	return 0;

}
