/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
#include <zephyr/net/socket.h>
#include <zephyr/sys/iterable_sections.h>

#include "sockets_internal.h"

LOG_MODULE_REGISTER(net_sock_dispatcher, CONFIG_NET_SOCKETS_LOG_LEVEL);

__net_socket struct dispatcher_context {
	int fd;
	int family;
	int type;
	int proto;
	bool is_used;
};

static struct dispatcher_context
	dispatcher_context[CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER_CONTEXT_MAX];

static K_MUTEX_DEFINE(dispatcher_lock);

static int sock_dispatch_create(int family, int type, int proto);

static bool is_tls(int proto)
{
	if ((proto >= IPPROTO_TLS_1_0 && proto <= IPPROTO_TLS_1_2) ||
	    (proto >= IPPROTO_DTLS_1_0 && proto <= IPPROTO_DTLS_1_2)) {
		return true;
	}

	return false;
}

static void dispatcher_ctx_free(struct dispatcher_context *ctx)
{
	(void)k_mutex_lock(&dispatcher_lock, K_FOREVER);

	/* Free the dispatcher entry. */
	memset(ctx, 0, sizeof(*ctx));

	k_mutex_unlock(&dispatcher_lock);
}

static int sock_dispatch_socket(struct dispatcher_context *ctx,
				net_socket_create_t socket_create)
{
	int new_fd, fd;
	const struct socket_op_vtable *vtable;
	void *obj;

	new_fd = socket_create(ctx->family, ctx->type, ctx->proto);
	if (new_fd < 0) {
		LOG_INF("Failed to create socket to dispatch");
		return -1;
	}

	obj = z_get_fd_obj_and_vtable(new_fd,
				      (const struct fd_op_vtable **)&vtable,
				      NULL);
	if (obj == NULL) {
		return -1;
	}

	/* Reassing FD with new obj and entry. */
	fd = ctx->fd;
	z_finalize_fd(fd, obj, (const struct fd_op_vtable *)vtable);

	/* Release FD that is no longer in use. */
	z_free_fd(new_fd);

	dispatcher_ctx_free(ctx);

	return fd;
}

static struct net_socket_register *sock_dispatch_find(int family, int type,
						      int proto, bool native_only)
{
	STRUCT_SECTION_FOREACH(net_socket_register, sock_family) {
		/* Ignore dispatcher itself. */
		if (sock_family->handler == sock_dispatch_create) {
			continue;
		}

		if (native_only && sock_family->is_offloaded) {
			continue;
		}

		if (sock_family->family != family &&
		    sock_family->family != AF_UNSPEC) {
			continue;
		}

		NET_ASSERT(sock_family->is_supported);

		if (!sock_family->is_supported(family, type, proto)) {
			continue;
		}

		return sock_family;
	}

	return NULL;
}

static int sock_dispatch_native(struct dispatcher_context *ctx)
{
	struct net_socket_register *sock_family;

	sock_family = sock_dispatch_find(ctx->family, ctx->type,
					 ctx->proto, true);
	if (sock_family == NULL) {
		errno = ENOENT;
		return -1;
	}

	return sock_dispatch_socket(ctx, sock_family->handler);
}

static int sock_dispatch_default(struct dispatcher_context *ctx)
{
	struct net_socket_register *sock_family;

	sock_family = sock_dispatch_find(ctx->family, ctx->type,
					 ctx->proto, false);
	if (sock_family == NULL) {
		errno = ENOENT;
		return -1;
	}

	return sock_dispatch_socket(ctx, sock_family->handler);
}

static ssize_t sock_dispatch_read_vmeth(void *obj, void *buffer, size_t count)
{
	int fd;
	const struct fd_op_vtable *vtable;
	void *new_obj;

	fd = sock_dispatch_default(obj);
	if (fd < 0) {
		return -1;
	}

	new_obj = z_get_fd_obj_and_vtable(fd, &vtable, NULL);
	if (new_obj == NULL) {
		return -1;
	}

	return vtable->read(new_obj, buffer, count);
}

static ssize_t sock_dispatch_write_vmeth(void *obj, const void *buffer,
					 size_t count)
{
	int fd;
	const struct fd_op_vtable *vtable;
	void *new_obj;

	fd = sock_dispatch_default(obj);
	if (fd < 0) {
		return -1;
	}

	new_obj = z_get_fd_obj_and_vtable(fd, &vtable, NULL);
	if (new_obj == NULL) {
		return -1;
	}

	return vtable->write(new_obj, buffer, count);
}

static int sock_dispatch_ioctl_vmeth(void *obj, unsigned int request,
				     va_list args)
{
	int fd;
	const struct fd_op_vtable *vtable;
	void *new_obj;

	if (request == ZFD_IOCTL_SET_LOCK) {
		/* Ignore set lock, used by FD logic. */
		return 0;
	}

	fd = sock_dispatch_default(obj);
	if (fd < 0) {
		return -1;
	}

	new_obj = z_get_fd_obj_and_vtable(fd, &vtable, NULL);
	if (new_obj == NULL) {
		return -1;
	}

	return vtable->ioctl(new_obj, request, args);
}

static int sock_dispatch_shutdown_vmeth(void *obj, int how)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_shutdown(fd, how);
}

static int sock_dispatch_bind_vmeth(void *obj, const struct sockaddr *addr,
				    socklen_t addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_bind(fd, addr, addrlen);
}

static int sock_dispatch_connect_vmeth(void *obj, const struct sockaddr *addr,
				       socklen_t addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_connect(fd, addr, addrlen);
}

static int sock_dispatch_listen_vmeth(void *obj, int backlog)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_listen(fd, backlog);
}

static int sock_dispatch_accept_vmeth(void *obj, struct sockaddr *addr,
				      socklen_t *addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_accept(fd, addr, addrlen);
}

static ssize_t sock_dispatch_sendto_vmeth(void *obj, const void *buf,
					  size_t len, int flags,
					  const struct sockaddr *addr,
					  socklen_t addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_sendto(fd, buf, len, flags, addr, addrlen);
}

static ssize_t sock_dispatch_sendmsg_vmeth(void *obj, const struct msghdr *msg,
					   int flags)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_sendmsg(fd, msg, flags);
}

static ssize_t sock_dispatch_recvfrom_vmeth(void *obj, void *buf,
					    size_t max_len, int flags,
					    struct sockaddr *addr,
					    socklen_t *addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_recvfrom(fd, buf, max_len, flags, addr, addrlen);
}

static int sock_dispatch_getsockopt_vmeth(void *obj, int level, int optname,
					  void *optval, socklen_t *optlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_getsockopt(fd, level, optname, optval, optlen);
}

static int sock_dispatch_setsockopt_vmeth(void *obj, int level, int optname,
					  const void *optval, socklen_t optlen)
{
	int fd;

	if ((level == SOL_SOCKET) && (optname == SO_BINDTODEVICE)) {
		struct net_if *iface;
		const struct device *dev;
		const struct ifreq *ifreq = optval;

		if ((ifreq == NULL) || (optlen != sizeof(*ifreq))) {
			errno = EINVAL;
			return -1;
		}

		dev = device_get_binding(ifreq->ifr_name);
		if (dev == NULL) {
			errno = ENODEV;
			return -1;
		}

		iface = net_if_lookup_by_dev(dev);
		if (iface == NULL) {
			errno = ENODEV;
			return -1;
		}

		if (net_if_socket_offload(iface) != NULL) {
			/* Offloaded socket interface - use associated socket implementation. */
			fd = sock_dispatch_socket(obj, net_if_socket_offload(iface));
		} else {
			/* Native interface - use native socket implementation. */
			fd = sock_dispatch_native(obj);
		}
	} else if ((level == SOL_TLS) && (optname == TLS_NATIVE)) {
		const int *tls_native = optval;
		struct dispatcher_context *ctx = obj;

		if ((tls_native == NULL) || (optlen != sizeof(int))) {
			errno = EINVAL;
			return -1;
		}

		if (!is_tls(ctx->proto)) {
			errno = ENOPROTOOPT;
			return -1;
		}

		if (*tls_native) {
			fd = sock_dispatch_native(obj);
		} else {
			/* No action needed */
			return 0;
		}
	} else {
		fd = sock_dispatch_default(obj);
	}

	if (fd < 0) {
		return -1;
	}

	return zsock_setsockopt(fd, level, optname, optval, optlen);
}

static int sock_dispatch_close_vmeth(void *obj)
{
	dispatcher_ctx_free(obj);

	return 0;
}

static int sock_dispatch_getpeername_vmeth(void *obj, struct sockaddr *addr,
					   socklen_t *addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_getpeername(fd, addr, addrlen);
}

static int sock_dispatch_getsockname_vmeth(void *obj, struct sockaddr *addr,
					   socklen_t *addrlen)
{
	int fd = sock_dispatch_default(obj);

	if (fd < 0) {
		return -1;
	}

	return zsock_getsockname(fd, addr, addrlen);
}

static const struct socket_op_vtable sock_dispatch_fd_op_vtable = {
	.fd_vtable = {
		.read = sock_dispatch_read_vmeth,
		.write = sock_dispatch_write_vmeth,
		.close = sock_dispatch_close_vmeth,
		.ioctl = sock_dispatch_ioctl_vmeth,
	},
	.shutdown = sock_dispatch_shutdown_vmeth,
	.bind = sock_dispatch_bind_vmeth,
	.connect = sock_dispatch_connect_vmeth,
	.listen = sock_dispatch_listen_vmeth,
	.accept = sock_dispatch_accept_vmeth,
	.sendto = sock_dispatch_sendto_vmeth,
	.sendmsg = sock_dispatch_sendmsg_vmeth,
	.recvfrom = sock_dispatch_recvfrom_vmeth,
	.getsockopt = sock_dispatch_getsockopt_vmeth,
	.setsockopt = sock_dispatch_setsockopt_vmeth,
	.getpeername = sock_dispatch_getpeername_vmeth,
	.getsockname = sock_dispatch_getsockname_vmeth,
};

static int sock_dispatch_create(int family, int type, int proto)
{
	struct dispatcher_context *entry = NULL;
	int fd = -1;

	(void)k_mutex_lock(&dispatcher_lock, K_FOREVER);

	for (int i = 0; i < ARRAY_SIZE(dispatcher_context); i++) {
		if (dispatcher_context[i].is_used) {
			continue;
		}

		entry = &dispatcher_context[i];
		break;
	}

	if (entry == NULL) {
		errno = ENOMEM;
		goto out;
	}

	if (sock_dispatch_find(family, type, proto, false) == NULL) {
		errno = EAFNOSUPPORT;
		goto out;
	}

	fd = z_reserve_fd();
	if (fd < 0) {
		goto out;
	}

	entry->fd = fd;
	entry->family = family;
	entry->type = type;
	entry->proto = proto;
	entry->is_used = true;

	z_finalize_fd(fd, entry,
		      (const struct fd_op_vtable *)&sock_dispatch_fd_op_vtable);

out:
	k_mutex_unlock(&dispatcher_lock);
	return fd;
}

static bool is_supported(int family, int type, int proto)
{
	return true;
}

NET_SOCKET_REGISTER(sock_dispatch, 0, AF_UNSPEC, is_supported,
		    sock_dispatch_create);
