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

#if defined(CONFIG_NET_DEBUG_SOCKETS)
#define SYS_LOG_DOMAIN "net/sock"
#define NET_LOG_ENABLED 1
#endif

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

/* Zephyr headers */
#include <kernel.h>
#include <net/socket.h>

struct getaddrinfo_state {
	const struct zsock_addrinfo *hints;
	struct k_sem sem;
	int status;
	u16_t idx;
	u16_t port;
};

static struct zsock_addrinfo ai_arr[2];
static struct getaddrinfo_state ai_state;

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;
	int proto;

	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 >= ARRAY_SIZE(ai_arr)) {
		NET_DBG("getaddrinfo entries overflow");
		return;
	}

	ai = ai_arr + state->idx;
	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;
		}
	}

	proto = IPPROTO_TCP;
	if (socktype == SOCK_DGRAM) {
		proto = IPPROTO_UDP;
	}

	ai->ai_socktype = socktype;
	ai->ai_protocol = proto;

	state->idx++;
}


int zsock_getaddrinfo(const char *host, const char *service,
		      const struct zsock_addrinfo *hints,
		      struct zsock_addrinfo **res)
{
	int family = AF_UNSPEC;
	long int port;
	int st1 = DNS_EAI_ADDRFAMILY, st2 = DNS_EAI_ADDRFAMILY;

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

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

	ai_state.hints = hints;
	ai_state.idx = 0;
	ai_state.port = htons(port);
	k_sem_init(&ai_state.sem, 0, UINT_MAX);

	/* Link entries in advance */
	ai_arr[0].ai_next = &ai_arr[1];

	/* Execute if AF_UNSPEC or AF_INET4 */
	if (family != AF_INET6) {
		dns_get_addr_info(host, DNS_QUERY_TYPE_A, NULL,
				  dns_resolve_cb, &ai_state, 1000);
		k_sem_take(&ai_state.sem, K_FOREVER);
		net_sin(&ai_arr[ai_state.idx - 1]._ai_addr)->sin_port =
								htons(port);
		st1 = ai_state.status;
	}

	/* Execute if AF_UNSPEC or AF_INET6 */
	if (family != AF_INET) {
		dns_get_addr_info(host, DNS_QUERY_TYPE_AAAA, NULL,
				  dns_resolve_cb, &ai_state, 1000);
		k_sem_take(&ai_state.sem, K_FOREVER);
		net_sin6(&ai_arr[ai_state.idx - 1]._ai_addr)->sin6_port =
								htons(port);
		st2 = ai_state.status;
	}

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

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

	*res = ai_arr;

	return 0;
}
