/* server.c */

/*
 * Copyright (c) 2017 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#if defined(CONFIG_NET_DEBUG_APP)
#define SYS_LOG_DOMAIN "net/app"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

#include <zephyr.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <net/net_core.h>
#include <net/net_ip.h>
#include <net/net_if.h>

#include <net/net_app.h>

#include "net_app_private.h"

#if defined(CONFIG_NET_TCP)
static void new_client(struct net_context *net_ctx,
		       const struct sockaddr *addr)
{
#if defined(CONFIG_NET_DEBUG_APP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof("[]:xxxxx")
	char buf[NET_IPV6_ADDR_LEN + PORT_STR];
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof(":xxxxx")
	char buf[NET_IPV4_ADDR_LEN + PORT_STR];
#endif

	NET_INFO("Connection from %s (%p)",
		 _net_app_sprint_ipaddr(buf, sizeof(buf), addr),
		 net_ctx);
#endif /* CONFIG_NET_DEBUG_APP */
}

static int get_avail_net_ctx(struct net_app_ctx *ctx)
{
	int i;

	for (i = 0; i < CONFIG_NET_APP_SERVER_NUM_CONN; i++) {
		if (!ctx->server.net_ctxs[i] ||
		    !net_context_is_used(ctx->server.net_ctxs[i])) {
			return i;
		}
	}

	return -1;
}

void _net_app_accept_cb(struct net_context *net_ctx,
			struct sockaddr *addr,
			socklen_t addrlen,
			int status, void *data)
{
	struct net_app_ctx *ctx = data;
	int i, ret;

	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	i = get_avail_net_ctx(ctx);

	if (i < 0 || status != 0 || !ctx->is_enabled) {
		/* We are already connected and there are no free context slots
		 * available so this new connection must be closed.
		 */
		net_context_put(net_ctx);

		if (ctx->cb.connect) {
			if (!status) {
				status = -ECONNREFUSED;
			}

			ctx->cb.connect(ctx, status, ctx->user_data);
		}

		if (i < 0) {
			NET_DBG("All connection slots occupied, new "
				"connection dropped");
		}

		return;
	}

	NET_DBG("[%d] Accepted net_ctx %p", i, net_ctx);

	ret = net_context_recv(net_ctx, ctx->recv_cb, K_NO_WAIT, ctx);
	if (ret < 0) {
		NET_DBG("Cannot set recv_cb (%d)", ret);
	}

	ctx->server.net_ctxs[i] = net_ctx;

	/* We need to set the backpointer here, as otherwise it is impossible
	 * to find the correct net_ctx from a list of net_ctxs.
	 */
	net_ctx->net_app = ctx;

	new_client(net_ctx, addr);

	if (ctx->cb.connect) {
		ctx->cb.connect(ctx, 0, ctx->user_data);
	}
}
#endif /* CONFIG_NET_TCP */

int net_app_listen(struct net_app_ctx *ctx)
{
	bool dual = false, v4_failed = false;
	int ret;

	if (!ctx) {
		return -EINVAL;
	}

	if (!ctx->is_init) {
		return -ENOENT;
	}

	if (ctx->app_type != NET_APP_SERVER) {
		return -EINVAL;
	}

#if defined(CONFIG_NET_IPV4)
	if (ctx->ipv4.local.sa_family == AF_UNSPEC) {
		ctx->ipv4.local.sa_family = AF_INET;
		dual = true;

		_net_app_set_local_addr(&ctx->ipv4.local, NULL,
					net_sin(&ctx->ipv4.local)->sin_port);
	}

	ret = _net_app_set_net_ctx(ctx, ctx->ipv4.ctx, &ctx->ipv4.local,
				   sizeof(struct sockaddr_in), ctx->proto);
	if (ret < 0) {
		if (ctx->ipv4.ctx) {
			net_context_put(ctx->ipv4.ctx);
			ctx->ipv4.ctx = NULL;
		}

		v4_failed = true;
	}
#if defined(CONFIG_NET_APP_DTLS)
	else {
		if (ctx->is_tls && ctx->proto == IPPROTO_UDP) {
			net_context_recv(ctx->ipv4.ctx, ctx->recv_cb,
					 K_NO_WAIT, ctx);
		}
	}
#endif
#endif /* CONFIG_NET_IPV4 */

	/* We ignore the IPv4 error if IPv6 is enabled */

#if defined(CONFIG_NET_IPV6)
	if (ctx->ipv6.local.sa_family == AF_UNSPEC || dual) {
		ctx->ipv6.local.sa_family = AF_INET6;

		_net_app_set_local_addr(&ctx->ipv6.local, NULL,
				       net_sin6(&ctx->ipv6.local)->sin6_port);
	}

	ret = _net_app_set_net_ctx(ctx, ctx->ipv6.ctx, &ctx->ipv6.local,
				   sizeof(struct sockaddr_in6), ctx->proto);
	if (ret < 0) {
		if (ctx->ipv6.ctx) {
			net_context_put(ctx->ipv6.ctx);
			ctx->ipv6.ctx = NULL;
		}

		if (!v4_failed) {
			ret = 0;
		}
	}
#if defined(CONFIG_NET_APP_DTLS)
	else {
		if (ctx->is_tls && ctx->proto == IPPROTO_UDP) {
			net_context_recv(ctx->ipv6.ctx, ctx->recv_cb,
					 K_NO_WAIT, ctx);
		}
	}
#endif
#endif /* CONFIG_NET_IPV6 */

	return ret;
}

int net_app_init_server(struct net_app_ctx *ctx,
			enum net_sock_type sock_type,
			enum net_ip_protocol proto,
			struct sockaddr *server_addr,
			u16_t port,
			void *user_data)
{
	int ret;

	if (!ctx) {
		return -EINVAL;
	}

	if (ctx->is_init) {
		return -EALREADY;
	}

#if defined(CONFIG_NET_IPV4)
	memset(&ctx->ipv4.local, 0, sizeof(ctx->ipv4.local));
#endif
#if defined(CONFIG_NET_IPV6)
	memset(&ctx->ipv6.local, 0, sizeof(ctx->ipv6.local));
#endif

	if (server_addr) {
		if (server_addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
			memcpy(&ctx->ipv4.local, server_addr,
			       sizeof(ctx->ipv4.local));
#else
			return -EPROTONOSUPPORT;
#endif
		}

		if (server_addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
			memcpy(&ctx->ipv6.local, server_addr,
			       sizeof(ctx->ipv6.local));
#else
			return -EPROTONOSUPPORT;
#endif
		}

		if (server_addr->sa_family == AF_UNSPEC) {
#if defined(CONFIG_NET_IPV4)
			net_sin(&ctx->ipv4.local)->sin_port =
				net_sin(server_addr)->sin_port;
#endif

#if defined(CONFIG_NET_IPV6)
			net_sin6(&ctx->ipv6.local)->sin6_port =
				net_sin6(server_addr)->sin6_port;
#endif
		}
	} else {
		if (port == 0) {
			return -EINVAL;
		}

#if defined(CONFIG_NET_IPV4)
		ctx->ipv4.local.sa_family = AF_INET;
		net_sin(&ctx->ipv4.local)->sin_port = htons(port);
#endif
#if defined(CONFIG_NET_IPV6)
		ctx->ipv6.local.sa_family = AF_INET6;
		net_sin6(&ctx->ipv6.local)->sin6_port = htons(port);
#endif
	}

	ctx->app_type = NET_APP_SERVER;
	ctx->user_data = user_data;
	ctx->send_data = net_context_sendto;
	ctx->recv_cb = _net_app_received;
	ctx->proto = proto;
	ctx->sock_type = sock_type;

	ret = _net_app_config_local_ctx(ctx, sock_type, proto, server_addr);
	if (ret < 0) {
		goto fail;
	}

	NET_ASSERT_INFO(ctx->default_ctx, "Default ctx not selected");

	ctx->is_init = true;

	_net_app_register(ctx);

fail:
	return ret;
}

#if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS)
static inline void new_server(struct net_app_ctx *ctx,
			      const char *server_banner)
{
#if defined(CONFIG_NET_DEBUG_APP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof("[]:xxxxx")
	char buf[NET_IPV6_ADDR_LEN + PORT_STR];
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof(":xxxxx")
	char buf[NET_IPV4_ADDR_LEN + PORT_STR];
#endif

#if defined(CONFIG_NET_IPV6)
	NET_INFO("%s %s (%p)", server_banner,
		 _net_app_sprint_ipaddr(buf, sizeof(buf), &ctx->ipv6.local),
		 ctx);
#endif

#if defined(CONFIG_NET_IPV4)
	NET_INFO("%s %s (%p)", server_banner,
		 _net_app_sprint_ipaddr(buf, sizeof(buf), &ctx->ipv4.local),
		 ctx);
#endif
#endif /* CONFIG_NET_DEBUG_APP */
}

static struct net_context *find_net_ctx(struct net_app_ctx *ctx,
					int *idx)
{
	int i;

	for (i = 0; i < CONFIG_NET_APP_SERVER_NUM_CONN; i++) {
		if (ctx->server.net_ctxs[i] &&
		    ctx->server.net_ctxs[i]->net_app == ctx &&
		    net_context_is_used(ctx->server.net_ctxs[i])) {
			*idx = i;
			return ctx->server.net_ctxs[i];
		}
	}

	return NULL;
}

static void tls_server_handler(struct net_app_ctx *ctx,
			       struct k_sem *startup_sync)
{
	int ret, i;

	NET_DBG("Starting TLS server thread for %p", ctx);

	ret = _net_app_tls_init(ctx, MBEDTLS_SSL_IS_SERVER);
	if (ret < 0) {
		NET_DBG("TLS server init failed");
		return;
	}

	k_sem_give(startup_sync);

	while (1) {
		struct net_context *net_ctx;

		_net_app_ssl_mainloop(ctx);

		NET_DBG("Closing %p connection", ctx);

		ctx->tls.close_requested = false;

		mbedtls_ssl_close_notify(&ctx->tls.mbedtls.ssl);

		ctx->tls.tx_pending = false;

		if (ctx->cb.close) {
			ctx->cb.close(ctx, -ESHUTDOWN, ctx->user_data);
		}

		net_ctx = find_net_ctx(ctx, &i);
		if (net_ctx) {
			NET_DBG("Server context %p removed", net_ctx);
			net_context_put(net_ctx);
			ctx->server.net_ctxs[i] = NULL;
		}
	}
}

#define TLS_STARTUP_TIMEOUT K_SECONDS(5)

bool _net_app_server_tls_enable(struct net_app_ctx *ctx)
{
	struct k_sem startup_sync;

	NET_ASSERT(ctx);

	if (!(ctx->tls.stack && ctx->tls.stack_size > 0)) {
		/* No stack or stack size is 0, we cannot enable */
		return false;
	}

	/* Start the thread that handles TLS traffic. */
	if (!ctx->tls.tid) {
		k_sem_init(&startup_sync, 0, 1);

		ctx->tls.tid = k_thread_create(&ctx->tls.thread,
					       ctx->tls.stack,
					       ctx->tls.stack_size,
					       (k_thread_entry_t)
							tls_server_handler,
					       ctx, &startup_sync, 0,
					       K_PRIO_COOP(7), 0, 0);

		/* Wait until we know that the TLS thread startup was ok */
		if (k_sem_take(&startup_sync, TLS_STARTUP_TIMEOUT) < 0) {
			NET_ERR("TLS server handler start failed");
			_net_app_tls_handler_stop(ctx);
			return false;
		}
	}

	return true;
}

bool _net_app_server_tls_disable(struct net_app_ctx *ctx)
{
	NET_ASSERT(ctx);

	if (!ctx->tls.tid) {
		return false;
	}

	_net_app_tls_handler_stop(ctx);

	return true;
}

int net_app_server_tls(struct net_app_ctx *ctx,
		       u8_t *request_buf,
		       size_t request_buf_len,
		       const char *server_banner,
		       u8_t *personalization_data,
		       size_t personalization_data_len,
		       net_app_cert_cb_t cert_cb,
		       net_app_entropy_src_cb_t entropy_src_cb,
		       struct k_mem_pool *pool,
		       k_thread_stack_t *stack,
		       size_t stack_size)
{
	if (!request_buf || request_buf_len == 0) {
		NET_ERR("Request buf must be set");
		return -EINVAL;
	}

	/* mbedtls cannot receive or send larger buffer as what is defined
	 * in a file pointed by CONFIG_MBEDTLS_CFG_FILE.
	 */
	if (request_buf_len > MBEDTLS_SSL_MAX_CONTENT_LEN) {
		NET_ERR("Request buf too large, max len is %d",
			MBEDTLS_SSL_MAX_CONTENT_LEN);
		return -EINVAL;
	}

	if (!cert_cb) {
		NET_ERR("Cert callback must be set");
		return -EINVAL;
	}

	if (server_banner) {
		new_server(ctx, server_banner);
	}

	ctx->tls.request_buf = request_buf;
	ctx->tls.request_buf_len = request_buf_len;
	ctx->is_tls = true;
	ctx->tls.stack = stack;
	ctx->tls.stack_size = stack_size;
	ctx->tls.mbedtls.cert_cb = cert_cb;
	ctx->tls.pool = pool;

	if (entropy_src_cb) {
		ctx->tls.mbedtls.entropy_src_cb = entropy_src_cb;
	} else {
		ctx->tls.mbedtls.entropy_src_cb = _net_app_entropy_source;
	}

	ctx->tls.mbedtls.personalization_data = personalization_data;
	ctx->tls.mbedtls.personalization_data_len = personalization_data_len;
	ctx->send_data = _net_app_tls_sendto;
	ctx->recv_cb = _net_app_tls_received;

	/* Then mbedtls specific initialization */
	return 0;
}
#endif /* CONFIG_NET_APP_TLS || CONFIG_NET_APP_DTLS */

bool net_app_server_enable(struct net_app_ctx *ctx)
{
	bool old;

	NET_ASSERT(ctx);

	old = ctx->is_enabled;

	ctx->is_enabled = true;

#if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS)
	if (ctx->is_tls) {
		_net_app_server_tls_enable(ctx);
	}
#endif
	return old;
}

bool net_app_server_disable(struct net_app_ctx *ctx)
{
	bool old;

	NET_ASSERT(ctx);

	old = ctx->is_enabled;

	ctx->is_enabled = false;

#if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS)
	if (ctx->is_tls) {
		_net_app_server_tls_disable(ctx);
	}
#endif
	return old;
}
