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

#include <logging/log.h>
#include <net/socket.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);
