/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/* libc headers */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* Zephyr headers */
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_sock_addr, CONFIG_NET_SOCKETS_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/socket.h>
#include <zephyr/net/socket_offload.h>
#include <zephyr/syscall_handler.h>

#if defined(CONFIG_DNS_RESOLVER) || defined(CONFIG_NET_IP)
#define ANY_RESOLVER

#if defined(CONFIG_DNS_RESOLVER_AI_MAX_ENTRIES)
#define AI_ARR_MAX CONFIG_DNS_RESOLVER_AI_MAX_ENTRIES
#else
#define AI_ARR_MAX 1
#endif /* defined(CONFIG_DNS_RESOLVER_AI_MAX_ENTRIES) */

/* Initialize static fields of addrinfo structure. A macro to let it work
 * with any sockaddr_* type.
 */
#define INIT_ADDRINFO(addrinfo, sockaddr) { \
		(addrinfo)->ai_addr = &(addrinfo)->_ai_addr; \
		(addrinfo)->ai_addrlen = sizeof(*(sockaddr)); \
		(addrinfo)->ai_canonname = (addrinfo)->_ai_canonname; \
		(addrinfo)->_ai_canonname[0] = '\0'; \
		(addrinfo)->ai_next = NULL; \
	}

#endif

#if defined(CONFIG_DNS_RESOLVER)

struct getaddrinfo_state {
	const struct zsock_addrinfo *hints;
	struct k_sem sem;
	int status;
	uint16_t idx;
	uint16_t port;
	uint16_t dns_id;
	struct zsock_addrinfo *ai_arr;
};

static void dns_resolve_cb(enum dns_resolve_status status,
			   struct dns_addrinfo *info, void *user_data)
{
	struct getaddrinfo_state *state = user_data;
	struct zsock_addrinfo *ai;
	int socktype = SOCK_STREAM;

	NET_DBG("dns status: %d", status);

	if (info == NULL) {
		if (status == DNS_EAI_ALLDONE) {
			status = 0;
		}
		state->status = status;
		k_sem_give(&state->sem);
		return;
	}

	if (state->idx >= AI_ARR_MAX) {
		NET_DBG("getaddrinfo entries overflow");
		return;
	}

	ai = &state->ai_arr[state->idx];
	if (state->idx > 0) {
		state->ai_arr[state->idx - 1].ai_next = ai;
	}

	memcpy(&ai->_ai_addr, &info->ai_addr, info->ai_addrlen);
	net_sin(&ai->_ai_addr)->sin_port = state->port;
	ai->ai_addr = &ai->_ai_addr;
	ai->ai_addrlen = info->ai_addrlen;
	memcpy(&ai->_ai_canonname, &info->ai_canonname,
	       sizeof(ai->_ai_canonname));
	ai->ai_canonname = ai->_ai_canonname;
	ai->ai_family = info->ai_family;

	if (state->hints) {
		if (state->hints->ai_socktype) {
			socktype = state->hints->ai_socktype;
		}
	}

	ai->ai_socktype = socktype;
	ai->ai_protocol = (socktype == SOCK_DGRAM) ? IPPROTO_UDP : IPPROTO_TCP;

	state->idx++;
}

static int exec_query(const char *host, int family,
		      struct getaddrinfo_state *ai_state)
{
	enum dns_query_type qtype = DNS_QUERY_TYPE_A;

	if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
		qtype = DNS_QUERY_TYPE_AAAA;
	}

	return dns_get_addr_info(host, qtype, &ai_state->dns_id,
				 dns_resolve_cb, ai_state,
				 CONFIG_NET_SOCKETS_DNS_TIMEOUT);
}

static int getaddrinfo_null_host(int port, const struct zsock_addrinfo *hints,
				struct zsock_addrinfo *res)
{
	if (!hints || !(hints->ai_flags & AI_PASSIVE)) {
		return DNS_EAI_FAIL;
	}

	/* For AF_UNSPEC, should we default to IPv6 or IPv4? */
	if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) {
		struct sockaddr_in *addr = net_sin(&res->_ai_addr);
		addr->sin_addr.s_addr = INADDR_ANY;
		addr->sin_port = htons(port);
		addr->sin_family = AF_INET;
		INIT_ADDRINFO(res, addr);
		res->ai_family = AF_INET;
	} else if (hints->ai_family == AF_INET6) {
		struct sockaddr_in6 *addr6 = net_sin6(&res->_ai_addr);
		addr6->sin6_addr = in6addr_any;
		addr6->sin6_port = htons(port);
		addr6->sin6_family = AF_INET6;
		INIT_ADDRINFO(res, addr6);
		res->ai_family = AF_INET6;
	} else {
		return DNS_EAI_FAIL;
	}

	if (hints->ai_socktype == SOCK_DGRAM) {
		res->ai_socktype = SOCK_DGRAM;
		res->ai_protocol = IPPROTO_UDP;
	} else {
		res->ai_socktype = SOCK_STREAM;
		res->ai_protocol = IPPROTO_TCP;
	}
	return 0;
}

int z_impl_z_zsock_getaddrinfo_internal(const char *host, const char *service,
				       const struct zsock_addrinfo *hints,
				       struct zsock_addrinfo *res)
{
	int family = AF_UNSPEC;
	int ai_flags = 0;
	long int port = 0;
	int st1 = DNS_EAI_ADDRFAMILY, st2 = DNS_EAI_ADDRFAMILY;
	struct sockaddr *ai_addr;
	int ret;
	struct getaddrinfo_state ai_state;

	if (hints) {
		family = hints->ai_family;
		ai_flags = hints->ai_flags;
	}

	if (ai_flags & AI_NUMERICHOST) {
		/* Asked to resolve host as numeric, but it wasn't possible
		 * to do that.
		 */
		return DNS_EAI_FAIL;
	}

	if (service) {
		port = strtol(service, NULL, 10);
		if (port < 1 || port > 65535) {
			return DNS_EAI_NONAME;
		}
	}

	if (host == NULL) {
		/* Per POSIX, both can't be NULL. */
		if (service == NULL) {
			errno = EINVAL;
			return DNS_EAI_SYSTEM;
		}

		return getaddrinfo_null_host(port, hints, res);
	}

	ai_state.hints = hints;
	ai_state.idx = 0U;
	ai_state.port = htons(port);
	ai_state.ai_arr = res;
	ai_state.dns_id = 0;
	k_sem_init(&ai_state.sem, 0, K_SEM_MAX_LIMIT);

	/* If the family is AF_UNSPEC, then we query IPv4 address first */
	ret = exec_query(host, family, &ai_state);
	if (ret == 0) {
		/* If the DNS query for reason fails so that the
		 * dns_resolve_cb() would not be called, then we want the
		 * semaphore to timeout so that we will not hang forever.
		 * So make the sem timeout longer than the DNS timeout so that
		 * we do not need to start to cancel any pending DNS queries.
		 */
		int ret = k_sem_take(&ai_state.sem,
				     K_MSEC(CONFIG_NET_SOCKETS_DNS_TIMEOUT +
					    100));
		if (ret == -EAGAIN) {
			(void)dns_cancel_addr_info(ai_state.dns_id);
			return DNS_EAI_AGAIN;
		}

		st1 = ai_state.status;
	} else {
		/* If we are returned -EPFNOSUPPORT then that will indicate
		 * wrong address family type queried. Check that and return
		 * DNS_EAI_ADDRFAMILY and set errno to EINVAL.
		 */
		if (ret == -EPFNOSUPPORT) {
			errno = EINVAL;
			st1 = DNS_EAI_ADDRFAMILY;
		} else {
			errno = -ret;
			st1 = DNS_EAI_SYSTEM;
		}
	}

	/* If family is AF_UNSPEC, the IPv4 query has been already done
	 * so we can do IPv6 query next if IPv6 is enabled in the config.
	 */
	if (family == AF_UNSPEC && IS_ENABLED(CONFIG_NET_IPV6)) {
		ret = exec_query(host, AF_INET6, &ai_state);
		if (ret == 0) {
			int ret = k_sem_take(
				&ai_state.sem,
				K_MSEC(CONFIG_NET_SOCKETS_DNS_TIMEOUT + 100));
			if (ret == -EAGAIN) {
				(void)dns_cancel_addr_info(ai_state.dns_id);
				return DNS_EAI_AGAIN;
			}

			st2 = ai_state.status;
		} else {
			errno = -ret;
			st2 = DNS_EAI_SYSTEM;
		}
	}

	if (ai_state.idx > 0) {
		ai_addr = &ai_state.ai_arr[ai_state.idx - 1]._ai_addr;
		net_sin(ai_addr)->sin_port = htons(port);
	}

	/* If both attempts failed, it's error */
	if (st1 && st2) {
		if (st1 != DNS_EAI_ADDRFAMILY) {
			return st1;
		}
		return st2;
	}

	/* Mark entry as last */
	ai_state.ai_arr[ai_state.idx - 1].ai_next = NULL;

	return 0;
}

#ifdef CONFIG_USERSPACE
static inline int z_vrfy_z_zsock_getaddrinfo_internal(const char *host,
					const char *service,
				       const struct zsock_addrinfo *hints,
				       struct zsock_addrinfo *res)
{
	struct zsock_addrinfo hints_copy;
	char *host_copy = NULL, *service_copy = NULL;
	uint32_t ret;

	if (hints) {
		Z_OOPS(z_user_from_copy(&hints_copy, (void *)hints,
					sizeof(hints_copy)));
	}
	Z_OOPS(Z_SYSCALL_MEMORY_ARRAY_WRITE(res, AI_ARR_MAX, sizeof(struct zsock_addrinfo)));

	if (service) {
		service_copy = z_user_string_alloc_copy((char *)service, 64);
		if (!service_copy) {
			ret = DNS_EAI_MEMORY;
			goto out;
		}
	}

	if (host) {
		host_copy = z_user_string_alloc_copy((char *)host, 64);
		if (!host_copy) {
			ret = DNS_EAI_MEMORY;
			goto out;
		}
	}

	ret = z_impl_z_zsock_getaddrinfo_internal(host_copy, service_copy,
						 hints ? &hints_copy : NULL,
						 (struct zsock_addrinfo *)res);
out:
	k_free(service_copy);
	k_free(host_copy);

	return ret;
}
#include <syscalls/z_zsock_getaddrinfo_internal_mrsh.c>
#endif /* CONFIG_USERSPACE */

#endif /* defined(CONFIG_DNS_RESOLVER) */

#if defined(CONFIG_NET_IP)
static int try_resolve_literal_addr(const char *host, const char *service,
				    const struct zsock_addrinfo *hints,
				    struct zsock_addrinfo *res)
{
	int family = AF_UNSPEC;
	int resolved_family = AF_UNSPEC;
	long port = 0;
	bool result;
	int socktype = SOCK_STREAM;
	int protocol = IPPROTO_TCP;

	if (!host) {
		return DNS_EAI_NONAME;
	}

	if (hints) {
		family = hints->ai_family;
		if (hints->ai_socktype == SOCK_DGRAM) {
			socktype = SOCK_DGRAM;
			protocol = IPPROTO_UDP;
		}
	}

	result = net_ipaddr_parse(host, strlen(host), &res->_ai_addr);

	if (!result) {
		return DNS_EAI_NONAME;
	}

	resolved_family = res->_ai_addr.sa_family;

	if ((family != AF_UNSPEC) && (resolved_family != family)) {
		return DNS_EAI_NONAME;
	}

	if (service) {
		port = strtol(service, NULL, 10);
		if (port < 1 || port > 65535) {
			return DNS_EAI_NONAME;
		}
	}

	res->ai_family = resolved_family;
	res->ai_socktype = socktype;
	res->ai_protocol = protocol;

	switch (resolved_family) {
	case AF_INET:
	{
		struct sockaddr_in *addr =
			(struct sockaddr_in *)&res->_ai_addr;

		INIT_ADDRINFO(res, addr);
		addr->sin_port = htons(port);
		addr->sin_family = AF_INET;
		break;
	}

	case AF_INET6:
	{
		struct sockaddr_in6 *addr =
			(struct sockaddr_in6 *)&res->_ai_addr;

		INIT_ADDRINFO(res, addr);
		addr->sin6_port = htons(port);
		addr->sin6_family = AF_INET6;
		break;
	}

	default:
		return DNS_EAI_NONAME;
	}

	return 0;
}
#endif /* CONFIG_NET_IP */

int zsock_getaddrinfo(const char *host, const char *service,
		      const struct zsock_addrinfo *hints,
		      struct zsock_addrinfo **res)
{
	if (IS_ENABLED(CONFIG_NET_SOCKETS_OFFLOAD)) {
		return socket_offload_getaddrinfo(host, service, hints, res);
	}

	int ret = DNS_EAI_FAIL;

#if defined(ANY_RESOLVER)
	*res = calloc(AI_ARR_MAX, sizeof(struct zsock_addrinfo));
	if (!(*res)) {
		return DNS_EAI_MEMORY;
	}
#endif

#if defined(CONFIG_NET_IP)
	/* Resolve literal address even if DNS is not available */
	if (ret) {
		ret = try_resolve_literal_addr(host, service, hints, *res);
	}
#endif

#if defined(CONFIG_DNS_RESOLVER)
	if (ret) {
		ret = z_zsock_getaddrinfo_internal(host, service, hints, *res);
	}
#endif

#if defined(ANY_RESOLVER)
	if (ret) {
		free(*res);
		*res = NULL;
	}
#endif

	return ret;
}

void zsock_freeaddrinfo(struct zsock_addrinfo *ai)
{
	if (IS_ENABLED(CONFIG_NET_SOCKETS_OFFLOAD)) {
		return socket_offload_freeaddrinfo(ai);
	}

	free(ai);
}

#define ERR(e) case DNS_ ## e: return #e
const char *zsock_gai_strerror(int errcode)
{
	switch (errcode) {
	ERR(EAI_BADFLAGS);
	ERR(EAI_NONAME);
	ERR(EAI_AGAIN);
	ERR(EAI_FAIL);
	ERR(EAI_NODATA);
	ERR(EAI_MEMORY);
	ERR(EAI_SYSTEM);
	ERR(EAI_SERVICE);

	default:
		return "EAI_UNKNOWN";
	}
}
#undef ERR
