/*
 * Copyright (c) 2020 Tobias Svehagen
 * Copyright (c) 2023, Meta
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ksched.h>
#include <zephyr/kernel.h>
#include <zephyr/net/socket.h>
#include <zephyr/posix/sys/eventfd.h>
#include <zephyr/sys/bitarray.h>
#include <zephyr/sys/fdtable.h>
#include <zephyr/sys/math_extras.h>

#define EFD_IN_USE_INTERNAL    0x1
#define EFD_FLAGS_SET_INTERNAL (EFD_SEMAPHORE | EFD_NONBLOCK)

struct eventfd {
	struct k_spinlock lock;
	eventfd_t cnt;
	int flags;
};

static ssize_t eventfd_rw_op(void *obj, void *buf, size_t sz,
			     int (*op)(struct eventfd *efd, eventfd_t *value));

SYS_BITARRAY_DEFINE_STATIC(efds_bitarray, CONFIG_EVENTFD_MAX);
static struct eventfd efds[CONFIG_EVENTFD_MAX];
static const struct fd_op_vtable eventfd_fd_vtable;

static inline bool eventfd_is_in_use(struct eventfd *efd)
{
	return (efd->flags & EFD_IN_USE_INTERNAL) != 0;
}

static inline bool eventfd_is_semaphore(struct eventfd *efd)
{
	return (efd->flags & EFD_SEMAPHORE) != 0;
}

static inline bool eventfd_is_blocking(struct eventfd *efd)
{
	return (efd->flags & EFD_NONBLOCK) == 0;
}

static int eventfd_poll_prepare(struct eventfd *efd,
				struct zsock_pollfd *pfd,
				struct k_poll_event **pev,
				struct k_poll_event *pev_end)
{
	if ((pfd->events & (ZSOCK_POLLOUT | ZSOCK_POLLIN)) != 0) {
		if (*pev == pev_end) {
			errno = ENOMEM;
			return -1;
		}
		**pev = (struct k_poll_event){0};
		(*pev)++;
	}

	return 0;
}

static int eventfd_poll_update(struct eventfd *efd,
			       struct zsock_pollfd *pfd,
			       struct k_poll_event **pev)
{
	if (pfd->events & ZSOCK_POLLIN) {
		pfd->revents |= ZSOCK_POLLIN * (efd->cnt > 0);
		(*pev)++;
	}

	if (pfd->events & ZSOCK_POLLOUT) {
		pfd->revents |= ZSOCK_POLLOUT * (efd->cnt < UINT64_MAX - 1);
		(*pev)++;
	}

	return 0;
}

static int eventfd_read_locked(struct eventfd *efd, eventfd_t *value)
{
	if (!eventfd_is_in_use(efd)) {
		/* file descriptor has been closed */
		return -EBADF;
	}

	if (efd->cnt == 0) {
		/* would block / try again */
		return -EAGAIN;
	}

	/* successful read */
	if (eventfd_is_semaphore(efd)) {
		*value = 1;
		--efd->cnt;
	} else {
		*value = efd->cnt;
		efd->cnt = 0;
	}

	return 0;
}

static int eventfd_write_locked(struct eventfd *efd, eventfd_t *value)
{
	eventfd_t result;

	if (!eventfd_is_in_use(efd)) {
		/* file descriptor has been closed */
		return -EBADF;
	}

	if (*value == UINT64_MAX) {
		/* not a permitted value */
		return -EINVAL;
	}

	if (u64_add_overflow(efd->cnt, *value, &result) || result == UINT64_MAX) {
		/* would block / try again */
		return -EAGAIN;
	}

	/* successful write */
	efd->cnt = result;

	return 0;
}

static ssize_t eventfd_read_op(void *obj, void *buf, size_t sz)
{
	return eventfd_rw_op(obj, buf, sz, eventfd_read_locked);
}

static ssize_t eventfd_write_op(void *obj, const void *buf, size_t sz)
{
	return eventfd_rw_op(obj, (eventfd_t *)buf, sz, eventfd_write_locked);
}

static int eventfd_close_op(void *obj)
{
	int ret;
	int err;
	k_spinlock_key_t key;
	struct k_mutex *lock = NULL;
	struct k_condvar *cond = NULL;
	struct eventfd *efd = (struct eventfd *)obj;

	if (k_is_in_isr()) {
		/* not covered by the man page, but necessary in Zephyr */
		errno = EWOULDBLOCK;
		return -1;
	}

	err = (int)z_get_obj_lock_and_cond(obj, &eventfd_fd_vtable, &lock, &cond);
	__ASSERT((bool)err, "z_get_obj_lock_and_cond() failed");
	__ASSERT_NO_MSG(lock != NULL);
	__ASSERT_NO_MSG(cond != NULL);

	err = k_mutex_lock(lock, K_FOREVER);
	__ASSERT(err == 0, "k_mutex_lock() failed: %d", err);

	key = k_spin_lock(&efd->lock);

	if (!eventfd_is_in_use(efd)) {
		errno = EBADF;
		ret = -1;
		goto unlock;
	}

	err = sys_bitarray_free(&efds_bitarray, 1, (struct eventfd *)obj - efds);
	__ASSERT(err == 0, "sys_bitarray_free() failed: %d", err);

	efd->flags = 0;
	efd->cnt = 0;

	ret = 0;

unlock:
	k_spin_unlock(&efd->lock, key);
	/* when closing an eventfd, broadcast to all waiters */
	err = k_condvar_broadcast(cond);
	__ASSERT(err == 0, "k_condvar_broadcast() failed: %d", err);
	err = k_mutex_unlock(lock);
	__ASSERT(err == 0, "k_mutex_unlock() failed: %d", err);

	return ret;
}

static int eventfd_ioctl_op(void *obj, unsigned int request, va_list args)
{
	int ret;
	k_spinlock_key_t key;
	struct eventfd *efd = (struct eventfd *)obj;

	/* note: zsock_poll_internal() has already taken the mutex */
	key = k_spin_lock(&efd->lock);

	if (!eventfd_is_in_use(efd)) {
		errno = EBADF;
		ret = -1;
		goto unlock;
	}

	switch (request) {
	case F_GETFL:
		ret = efd->flags & EFD_FLAGS_SET_INTERNAL;
		break;

	case F_SETFL: {
		int flags;

		flags = va_arg(args, int);

		if (flags & ~EFD_FLAGS_SET_INTERNAL) {
			errno = EINVAL;
			ret = -1;
		} else {
			efd->flags = flags;
			ret = 0;
		}
	} break;

	case ZFD_IOCTL_POLL_PREPARE: {
		struct zsock_pollfd *pfd;
		struct k_poll_event **pev;
		struct k_poll_event *pev_end;

		pfd = va_arg(args, struct zsock_pollfd *);
		pev = va_arg(args, struct k_poll_event **);
		pev_end = va_arg(args, struct k_poll_event *);

		ret = eventfd_poll_prepare(obj, pfd, pev, pev_end);
	} break;

	case ZFD_IOCTL_POLL_UPDATE: {
		struct zsock_pollfd *pfd;
		struct k_poll_event **pev;

		pfd = va_arg(args, struct zsock_pollfd *);
		pev = va_arg(args, struct k_poll_event **);

		ret = eventfd_poll_update(obj, pfd, pev);
	} break;

	default:
		errno = EOPNOTSUPP;
		ret = -1;
		break;
	}

unlock:
	k_spin_unlock(&efd->lock, key);

	return ret;
}

static const struct fd_op_vtable eventfd_fd_vtable = {
	.read = eventfd_read_op,
	.write = eventfd_write_op,
	.close = eventfd_close_op,
	.ioctl = eventfd_ioctl_op,
};

/* common to both eventfd_read_op() and eventfd_write_op() */
static ssize_t eventfd_rw_op(void *obj, void *buf, size_t sz,
			     int (*op)(struct eventfd *efd, eventfd_t *value))
{
	int err;
	ssize_t ret;
	k_spinlock_key_t key;
	struct eventfd *efd = obj;
	struct k_mutex *lock = NULL;
	struct k_condvar *cond = NULL;

	if (sz < sizeof(eventfd_t)) {
		errno = EINVAL;
		return -1;
	}

	if (buf == NULL) {
		errno = EFAULT;
		return -1;
	}

	key = k_spin_lock(&efd->lock);

	if (!eventfd_is_blocking(efd)) {
		/*
		 * Handle the non-blocking case entirely within this scope
		 */
		ret = op(efd, buf);
		if (ret < 0) {
			errno = -ret;
			ret = -1;
		} else {
			ret = sizeof(eventfd_t);
		}

		goto unlock_spin;
	}

	/*
	 * Handle the blocking case below
	 */
	__ASSERT_NO_MSG(eventfd_is_blocking(efd));

	if (k_is_in_isr()) {
		/* not covered by the man page, but necessary in Zephyr */
		errno = EWOULDBLOCK;
		ret = -1;
		goto unlock_spin;
	}

	err = (int)z_get_obj_lock_and_cond(obj, &eventfd_fd_vtable, &lock, &cond);
	__ASSERT((bool)err, "z_get_obj_lock_and_cond() failed");
	__ASSERT_NO_MSG(lock != NULL);
	__ASSERT_NO_MSG(cond != NULL);

	/* do not hold a spinlock when taking a mutex */
	k_spin_unlock(&efd->lock, key);
	err = k_mutex_lock(lock, K_FOREVER);
	__ASSERT(err == 0, "k_mutex_lock() failed: %d", err);

	while (true) {
		/* retake the spinlock */
		key = k_spin_lock(&efd->lock);

		ret = op(efd, buf);
		switch (ret) {
		case -EAGAIN:
			/* not an error in blocking mode. break and try again */
			break;
		case 0:
			/* success! */
			ret = sizeof(eventfd_t);
			goto unlock_mutex;
		default:
			/* some other error */
			__ASSERT_NO_MSG(ret < 0);
			errno = -ret;
			ret = -1;
			goto unlock_mutex;
		}

		/* do not hold a spinlock when taking a mutex */
		k_spin_unlock(&efd->lock, key);

		/* wait for a write or close */
		err = k_condvar_wait(cond, lock, K_FOREVER);
		__ASSERT(err == 0, "k_condvar_wait() failed: %d", err);
	}

unlock_mutex:
	k_spin_unlock(&efd->lock, key);
	/* only wake a single waiter */
	err = k_condvar_signal(cond);
	__ASSERT(err == 0, "k_condvar_signal() failed: %d", err);
	err = k_mutex_unlock(lock);
	__ASSERT(err == 0, "k_mutex_unlock() failed: %d", err);
	goto out;

unlock_spin:
	k_spin_unlock(&efd->lock, key);

out:
	return ret;
}

/*
 * Public-facing API
 */

int eventfd(unsigned int initval, int flags)
{
	int fd = 1;
	size_t offset;
	struct eventfd *efd = NULL;

	if (flags & ~EFD_FLAGS_SET_INTERNAL) {
		errno = EINVAL;
		return -1;
	}

	if (sys_bitarray_alloc(&efds_bitarray, 1, &offset) < 0) {
		errno = ENOMEM;
		return -1;
	}

	efd = &efds[offset];

	fd = z_reserve_fd();
	if (fd < 0) {
		sys_bitarray_free(&efds_bitarray, 1, offset);
		return -1;
	}

	efd->flags = EFD_IN_USE_INTERNAL | flags;
	efd->cnt = initval;

	z_finalize_fd(fd, efd, &eventfd_fd_vtable);

	return fd;
}

int eventfd_read(int fd, eventfd_t *value)
{
	int ret;
	void *obj;

	obj = z_get_fd_obj(fd, &eventfd_fd_vtable, EBADF);
	if (obj == NULL) {
		return -1;
	}

	ret = eventfd_rw_op(obj, value, sizeof(eventfd_t), eventfd_read_locked);
	__ASSERT_NO_MSG(ret == -1 || ret == sizeof(eventfd_t));
	if (ret < 0) {
		return -1;
	}

	return 0;
}

int eventfd_write(int fd, eventfd_t value)
{
	int ret;
	void *obj;

	obj = z_get_fd_obj(fd, &eventfd_fd_vtable, EBADF);
	if (obj == NULL) {
		return -1;
	}

	ret = eventfd_rw_op(obj, &value, sizeof(eventfd_t), eventfd_write_locked);
	__ASSERT_NO_MSG(ret == -1 || ret == sizeof(eventfd_t));
	if (ret < 0) {
		return -1;
	}

	return 0;
}
