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

#if defined(CONFIG_NET_DEBUG_HTTP)
#if defined(CONFIG_HTTPS)
#define SYS_LOG_DOMAIN "https/server"
#else
#define SYS_LOG_DOMAIN "http/server"
#endif
#define NET_LOG_ENABLED 1
#endif

#define RX_EXTRA_DEBUG 0

#include <misc/printk.h>

#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/net_context.h>

#include <net/http.h>

#if defined(CONFIG_HTTPS)
static void https_enable(struct http_server_ctx *ctx);
static void https_disable(struct http_server_ctx *ctx);

#if defined(MBEDTLS_DEBUG_C)
#include <mbedtls/debug.h>
/* - Debug levels (from ext/lib/crypto/mbedtls/include/mbedtls/debug.h)
 *    - 0 No debug
 *    - 1 Error
 *    - 2 State change
 *    - 3 Informational
 *    - 4 Verbose
 */
#define DEBUG_THRESHOLD 0
#endif

#endif /* CONFIG_HTTPS */

#define HTTP_DEFAULT_PORT  80
#define HTTPS_DEFAULT_PORT 443

#define RC_STR(rc)	(rc == 0 ? "OK" : "ERROR")

#define HTTP_STATUS_200_OK	"HTTP/1.1 200 OK\r\n" \
				"Content-Type: text/html\r\n" \
				"Transfer-Encoding: chunked\r\n" \
				"\r\n"

#define HTTP_STATUS_400_BR	"HTTP/1.1 400 Bad Request\r\n" \
				"\r\n"

#define HTTP_STATUS_403_FBD	"HTTP/1.1 403 Forbidden\r\n" \
				"\r\n"

#define HTTP_STATUS_404_NF	"HTTP/1.1 404 Not Found\r\n" \
				"\r\n"

#if defined(CONFIG_NET_DEBUG_HTTP_CONN)
/** List of HTTP connections */
static sys_slist_t http_conn;

static http_server_cb_t ctx_mon;
static void *mon_user_data;

static void http_server_conn_add(struct http_server_ctx *ctx)
{
	sys_slist_prepend(&http_conn, &ctx->node);

	if (ctx_mon) {
		ctx_mon(ctx, mon_user_data);
	}
}

static void http_server_conn_del(struct http_server_ctx *ctx)
{
	sys_slist_find_and_remove(&http_conn, &ctx->node);
}

void http_server_conn_foreach(http_server_cb_t cb, void *user_data)
{
	struct http_server_ctx *ctx;

	SYS_SLIST_FOR_EACH_CONTAINER(&http_conn, ctx, node) {
		cb(ctx, user_data);
	}
}

void http_server_conn_monitor(http_server_cb_t cb, void *user_data)
{
	ctx_mon = cb;
	mon_user_data = user_data;
}
#else
#define http_server_conn_add(...)
#define http_server_conn_del(...)
#endif /* CONFIG_NET_DEBUG_HTTP_CONN */

static inline u16_t http_strlen(const char *str)
{
	if (str) {
		return strlen(str);
	}

	return 0;
}

static int http_add_header(struct net_pkt *pkt, s32_t timeout, const char *str)
{
	if (net_pkt_append_all(pkt, strlen(str), (u8_t *)str, timeout)) {
		return 0;
	}

	return -ENOMEM;
}

static int http_add_chunk(struct net_pkt *pkt, s32_t timeout, const char *str)
{
	char chunk_header[16];
	u16_t str_len;
	bool ret;

	str_len = http_strlen(str);

	snprintk(chunk_header, sizeof(chunk_header), "%x\r\n", str_len);

	ret = net_pkt_append_all(pkt, strlen(chunk_header), chunk_header,
				 timeout);
	if (!ret) {
		return -ENOMEM;
	}

	if (str_len > 0) {
		ret = net_pkt_append_all(pkt, str_len, (u8_t *)str, timeout);
		if (!ret) {
			return -ENOMEM;
		}
	}

	ret = net_pkt_append_all(pkt, sizeof(HTTP_CRLF) - 1, HTTP_CRLF,
				 timeout);
	if (!ret) {
		return -ENOMEM;
	}

	return 0;
}

static void req_timer_cancel(struct http_server_ctx *ctx)
{
	ctx->req.timer_cancelled = true;
	k_delayed_work_cancel(&ctx->req.timer);

	NET_DBG("Context %p request timer cancelled", ctx);
}

static void req_timeout(struct k_work *work)
{
	struct http_server_ctx *ctx = CONTAINER_OF(work,
						   struct http_server_ctx,
						   req.timer);

	if (ctx->req.timer_cancelled) {
		return;
	}

	NET_DBG("Context %p request timeout", ctx);

	net_context_unref(ctx->req.net_ctx);
	ctx->req.net_ctx = NULL;

	http_server_conn_del(ctx);
}

static void pkt_sent(struct net_context *context,
		     int status,
		     void *token,
		     void *user_data)
{
	s32_t timeout = POINTER_TO_INT(token);
	struct http_server_ctx *ctx = user_data;

	req_timer_cancel(ctx);

	if (timeout == K_NO_WAIT) {
		/* We can just close the context after the packet is sent. */
		net_context_unref(context);
		http_server_conn_del(ctx);
	} else if (timeout > 0) {
		NET_DBG("Context %p starting timer", ctx);

		k_delayed_work_submit(&ctx->req.timer, timeout);

		ctx->req.timer_cancelled = false;
	}

	/* Note that if the timeout is K_FOREVER, we do not close
	 * the connection.
	 */
}

int http_response_wait(struct http_server_ctx *ctx, const char *http_header,
		       const char *html_payload, s32_t timeout)
{
	struct net_pkt *pkt;
	int ret = -EINVAL;

	pkt = net_pkt_get_tx(ctx->req.net_ctx, ctx->timeout);
	if (!pkt) {
		return ret;
	}

	ret = http_add_header(pkt, ctx->timeout, http_header);
	if (ret != 0) {
		goto exit_routine;
	}

	if (html_payload) {
		ret = http_add_chunk(pkt, ctx->timeout, html_payload);
		if (ret != 0) {
			goto exit_routine;
		}

		/* like EOF */
		ret = http_add_chunk(pkt, ctx->timeout, NULL);
		if (ret != 0) {
			goto exit_routine;
		}
	}

	net_pkt_set_appdatalen(pkt, net_buf_frags_len(pkt->frags));

	ret = ctx->send_data(pkt, pkt_sent, 0, INT_TO_POINTER(timeout), ctx);
	if (ret != 0) {
		goto exit_routine;
	}

	pkt = NULL;

exit_routine:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return ret;
}

int http_response(struct http_server_ctx *ctx, const char *http_header,
		  const char *html_payload)
{
	return http_response_wait(ctx, http_header, html_payload, K_NO_WAIT);
}

int http_response_400(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_400_BR, html_payload);
}

int http_response_403(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_403_FBD, html_payload);
}

int http_response_404(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_404_NF, html_payload);
}

int http_server_set_local_addr(struct sockaddr *addr, const char *myaddr,
			       u16_t port)
{
	if (!addr) {
		return -EINVAL;
	}

	if (myaddr) {
		void *inaddr;

		if (addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
			inaddr = &net_sin(addr)->sin_addr;
			net_sin(addr)->sin_port = htons(port);
#else
			return -EPFNOSUPPORT;
#endif
		} else if (addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
			inaddr = &net_sin6(addr)->sin6_addr;
			net_sin6(addr)->sin6_port = htons(port);
#else
			return -EPFNOSUPPORT;
#endif
		} else {
			return -EAFNOSUPPORT;
		}

		return net_addr_pton(addr->family, myaddr, inaddr);
	}

	/* If the caller did not supply the address where to bind, then
	 * try to figure it out ourselves.
	 */
	if (addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		net_ipaddr_copy(&net_sin6(addr)->sin6_addr,
				net_if_ipv6_select_src_addr(NULL,
					(struct in6_addr *)
					net_ipv6_unspecified_address()));
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		struct net_if *iface = net_if_get_default();

		/* For IPv4 we take the first address in the interface */
		net_ipaddr_copy(&net_sin(addr)->sin_addr,
				&iface->ipv4.unicast[0].address.in_addr);
#else
		return -EPFNOSUPPORT;
#endif
	}

	return 0;
}

struct http_root_url *http_server_add_url(struct http_server_urls *my,
					  const char *url, u8_t flags,
					  http_url_cb_t write_cb)
{
	int i;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		if (my->urls[i].is_used) {
			continue;
		}

		my->urls[i].is_used = true;
		my->urls[i].root = url;

		/* This will speed-up some future operations */
		my->urls[i].root_len = strlen(url);
		my->urls[i].flags = flags;
		my->urls[i].write_cb = write_cb;

		return &my->urls[i];
	}

	return NULL;
}

int http_server_del_url(struct http_server_urls *my, const char *url)
{
	int i;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		if (!my->urls[i].is_used) {
			continue;
		}

		if (strncmp(my->urls[i].root, url, my->urls[i].root_len)) {
			continue;
		}

		my->urls[i].is_used = false;
		my->urls[i].root = NULL;

		return 0;
	}

	return -ENOENT;
}

struct http_root_url *http_server_add_default(struct http_server_urls *my,
					      http_url_cb_t write_cb)
{
	if (my->default_url.is_used) {
		return NULL;
	}

	my->default_url.is_used = true;
	my->default_url.root = NULL;
	my->default_url.root_len = 0;
	my->default_url.flags = 0;
	my->default_url.write_cb = write_cb;

	return &my->default_url;
}

int http_server_del_default(struct http_server_urls *my)
{
	if (!my->default_url.is_used) {
		return -ENOENT;
	}

	my->default_url.is_used = false;

	return 0;
}

#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
static char *sprint_ipaddr(char *buf, int buflen, const struct sockaddr *addr)
{
	if (addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		char ipaddr[NET_IPV6_ADDR_LEN];

		net_addr_ntop(addr->family,
			      &net_sin6(addr)->sin6_addr,
			      ipaddr, sizeof(ipaddr));
		snprintk(buf, buflen, "[%s]:%u", ipaddr,
			 ntohs(net_sin6(addr)->sin6_port));
#endif
	} else if (addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		char ipaddr[NET_IPV4_ADDR_LEN];

		net_addr_ntop(addr->family,
			      &net_sin(addr)->sin_addr,
			      ipaddr, sizeof(ipaddr));
		snprintk(buf, buflen, "%s:%u", ipaddr,
			 ntohs(net_sin(addr)->sin_port));
#endif
	}

	return buf;
}
#endif /* CONFIG_NET_DEBUG_HTTP */

static inline void new_client(struct http_server_ctx *http_ctx,
			      struct net_context *net_ctx,
			      const struct sockaddr *addr)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (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("%s connection from %s (%p)",
		 http_ctx->is_https ? "HTTPS" : "HTTP",
		 sprint_ipaddr(buf, sizeof(buf), addr),
		 net_ctx);
#endif /* CONFIG_NET_DEBUG_HTTP */
}

static inline void new_server(struct http_server_ctx *ctx,
			      const char *server_banner,
			      const struct sockaddr *addr)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (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 (addr) {
		NET_INFO("%s %s (%p)", server_banner,
			 sprint_ipaddr(buf, sizeof(buf), addr), ctx);
	} else {
		NET_INFO("%s (%p)", server_banner, ctx);
	}
#endif /* CONFIG_NET_DEBUG_HTTP */
}

static int on_header_field(struct http_parser *parser,
			   const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	if (ctx->req.field_values_ctr >= CONFIG_HTTP_HEADER_FIELD_ITEMS) {
		return 0;
	}

	ctx->req.field_values[ctx->req.field_values_ctr].key = at;
	ctx->req.field_values[ctx->req.field_values_ctr].key_len = length;

	return 0;
}

static int on_header_value(struct http_parser *parser,
			   const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	if (ctx->req.field_values_ctr >= CONFIG_HTTP_HEADER_FIELD_ITEMS) {
		return 0;
	}

	ctx->req.field_values[ctx->req.field_values_ctr].value = at;
	ctx->req.field_values[ctx->req.field_values_ctr].value_len = length;

	ctx->req.field_values_ctr++;

	return 0;
}

static int on_url(struct http_parser *parser, const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	ctx->req.url = at;
	ctx->req.url_len = length;

	http_server_conn_add(ctx);

	return 0;
}

static int parser_init(struct http_server_ctx *ctx)
{
	memset(ctx->req.field_values, 0, sizeof(ctx->req.field_values));

	ctx->req.settings.on_header_field = on_header_field;
	ctx->req.settings.on_header_value = on_header_value;
	ctx->req.settings.on_url = on_url;

	http_parser_init(&ctx->req.parser, HTTP_REQUEST);

	ctx->req.parser.data = ctx;

	return 0;
}

static int http_url_cmp(const char *url, u16_t url_len,
			const char *root_url, u16_t root_url_len)
{
	if (url_len < root_url_len) {
		return -EINVAL;
	}

	if (memcmp(url, root_url, root_url_len) == 0) {
		if (url_len == root_url_len) {
			return 0;
		}

		/* Here we evaluate the following conditions:
		 * root_url = /images, url = /images/ -> OK
		 * root_url = /images/, url = /images/img.png -> OK
		 * root_url = /images/, url = /images_and_docs -> ERROR
		 */
		if (url_len > root_url_len) {
			if (root_url[root_url_len - 1] == '/') {
				return 0;
			}

			if (url[root_url_len] == '/') {
				return 0;
			}
		}
	}

	return -EINVAL;
}

static struct http_root_url *http_url_find(struct http_server_ctx *http_ctx)
{
	u16_t url_len = http_ctx->req.url_len;
	const char *url = http_ctx->req.url;
	struct http_root_url *root_url;
	u8_t i;
	int ret;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		root_url = &http_ctx->urls->urls[i];
		if (!root_url->is_used) {
			continue;
		}

		ret = http_url_cmp(url, url_len,
				   root_url->root, root_url->root_len);
		if (!ret) {
			return root_url;
		}
	}

	return NULL;
}

static int http_process_recv(struct http_server_ctx *http_ctx)
{
	struct http_root_url *root_url;
	int ret;

	root_url = http_url_find(http_ctx);
	if (!root_url) {
		root_url = &http_ctx->urls->default_url;
		if (!root_url->is_used) {
			NET_DBG("No default handler found (%p)", http_ctx);
			ret = -ENOENT;
			goto out;
		}
	}

	if (root_url->write_cb) {
		NET_DBG("Calling handler %p context %p",
			root_url->write_cb, http_ctx);
		ret = root_url->write_cb(http_ctx);
	} else {
		NET_ERR("No handler for %s", http_ctx->req.url);
		ret = -ENOENT;
	}

out:
	return ret;
}

static void http_recv(struct net_context *net_ctx,
		      struct net_pkt *pkt, int status,
		      void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;
	struct net_buf *frag;
	size_t start = http_ctx->req.data_len;
	int parsed_len;
	int header_len;
	u16_t len = 0, recv_len;

	if (!pkt) {
		NET_DBG("Connection closed by peer");
		return;
	}

	if (!http_ctx->enabled) {
		goto quit;
	}

	recv_len = net_pkt_appdatalen(pkt);
	if (recv_len == 0) {
		/* don't print info about zero-length app data buffers */
		goto quit;
	}

	if (status) {
		NET_DBG("Status %d <%s>", status, RC_STR(status));
		goto out;
	}

	/* Get rid of possible IP headers in the first fragment. */
	frag = pkt->frags;

	header_len = net_pkt_appdata(pkt) - frag->data;

	NET_DBG("Received %d bytes data", net_pkt_appdatalen(pkt));

	/* After this pull, the frag->data points directly to application data.
	 */
	net_buf_pull(frag, header_len);

	while (frag) {
		/* If this fragment cannot be copied to result buf,
		 * then parse what we have which will cause the callback to be
		 * called in function on_body(), and continue copying.
		 */
		if (http_ctx->req.data_len + frag->len >
		    http_ctx->req.request_buf_len) {

			/* If the caller has not supplied a callback, then
			 * we cannot really continue if the request buffer
			 * overflows. Set the data_len to mark how many bytes
			 * should be needed in the response_buf.
			 */
			if (http_process_recv(http_ctx) < 0) {
				http_ctx->req.data_len = net_pkt_get_len(pkt);
				goto out;
			}

			parsed_len =
				http_parser_execute(&http_ctx->req.parser,
						    &http_ctx->req.settings,
						    http_ctx->req.request_buf +
						    start,
						    len);
			if (parsed_len <= 0) {
				goto fail;
			}

			http_ctx->req.data_len = 0;
			len = 0;
			start = 0;
		}

		memcpy(http_ctx->req.request_buf + http_ctx->req.data_len,
		       frag->data, frag->len);

		http_ctx->req.data_len += frag->len;
		len += frag->len;
		frag = frag->frags;
	}

out:
	parsed_len = http_parser_execute(&http_ctx->req.parser,
					 &http_ctx->req.settings,
					 http_ctx->req.request_buf + start,
					 len);
	if (parsed_len < 0) {
fail:
		NET_DBG("Received %u bytes, only parsed %d bytes (%s %s)",
			recv_len, parsed_len,
			http_errno_name(http_ctx->req.parser.http_errno),
			http_errno_description(
				http_ctx->req.parser.http_errno));
	}

	if (http_ctx->req.parser.http_errno != HPE_OK) {
		http_response_400(http_ctx, NULL);
	} else {
		http_process_recv(http_ctx);
	}

quit:
	http_parser_init(&http_ctx->req.parser, HTTP_REQUEST);
	http_ctx->req.data_len = 0;
	net_pkt_unref(pkt);
}

static void accept_cb(struct net_context *net_ctx,
		      struct sockaddr *addr, socklen_t addrlen,
		      int status, void *data)
{
	struct http_server_ctx *http_ctx = data;

	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	if (status != 0) {
		net_context_put(net_ctx);
		return;
	}

	/* If we receive a HTTP request and if the earlier context is still
	 * active and it is not the same as the new one, then close the earlier
	 * one. Otherwise it is possible that the context will be left into
	 * TCP ESTABLISHED state and would never be released. Example of this
	 * is that we had IPv4 connection active and then IPv6 connection is
	 * established, in this case we disconnect the IPv4 here.
	 */
	if (http_ctx->req.net_ctx && http_ctx->req.net_ctx != net_ctx &&
	    net_context_get_state(http_ctx->req.net_ctx) ==
						      NET_CONTEXT_CONNECTED) {
		net_context_unref(http_ctx->req.net_ctx);
	}

	http_ctx->req.net_ctx = net_ctx;

	new_client(http_ctx, net_ctx, addr);

	net_context_recv(net_ctx, http_ctx->recv_cb, K_NO_WAIT, http_ctx);
}

static int set_net_ctx(struct http_server_ctx *http_ctx,
		       struct net_context *ctx,
		       struct sockaddr *addr,
		       socklen_t socklen)
{
	int ret;

	ret = net_context_bind(ctx, addr, socklen);
	if (ret < 0) {
		NET_ERR("Cannot bind context (%d)", ret);
		goto out;
	}

	ret = net_context_listen(ctx, 0);
	if (ret < 0) {
		NET_ERR("Cannot listen context (%d)", ret);
		goto out;
	}

	ret = net_context_accept(ctx, accept_cb, 0, http_ctx);
	if (ret < 0) {
		NET_ERR("Cannot accept context (%d)", ret);
		goto out;
	}

out:
	return ret;
}

#if defined(CONFIG_NET_IPV4)
static int setup_ipv4_ctx(struct http_server_ctx *http_ctx,
			  struct sockaddr *addr)
{
	socklen_t socklen;
	int ret;

	socklen = sizeof(struct sockaddr_in);

	ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP,
			      &http_ctx->net_ipv4_ctx);
	if (ret < 0) {
		NET_ERR("Cannot get network context (%d)", ret);
		http_ctx->net_ipv4_ctx = NULL;
		return ret;
	}

	if (addr->family == AF_UNSPEC) {
		addr->family = AF_INET;

		http_server_set_local_addr(addr, NULL,
					   net_sin(addr)->sin_port);
	}

	ret = set_net_ctx(http_ctx, http_ctx->net_ipv4_ctx,
			  addr, socklen);
	if (ret < 0) {
		net_context_put(http_ctx->net_ipv4_ctx);
		http_ctx->net_ipv4_ctx = NULL;
	}

	return ret;
}
#endif

#if defined(CONFIG_NET_IPV6)
int setup_ipv6_ctx(struct http_server_ctx *http_ctx, struct sockaddr *addr)
{
	socklen_t socklen;
	int ret;

	socklen = sizeof(struct sockaddr_in6);

	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP,
			      &http_ctx->net_ipv6_ctx);
	if (ret < 0) {
		NET_ERR("Cannot get network context (%d)", ret);
		http_ctx->net_ipv6_ctx = NULL;
		return ret;
	}

	if (addr->family == AF_UNSPEC) {
		addr->family = AF_INET6;

		http_server_set_local_addr(addr, NULL,
					   net_sin6(addr)->sin6_port);
	}

	ret = set_net_ctx(http_ctx, http_ctx->net_ipv6_ctx,
			  addr, socklen);
	if (ret < 0) {
		net_context_put(http_ctx->net_ipv6_ctx);
		http_ctx->net_ipv6_ctx = NULL;
	}

	return ret;
}
#endif

static int init_net(struct http_server_ctx *ctx,
		    struct sockaddr *server_addr,
		    u16_t port)
{
	struct sockaddr addr;
	int ret;

	memset(&addr, 0, sizeof(addr));

	if (server_addr) {
		memcpy(&addr, server_addr, sizeof(addr));
	} else {
		addr.family = AF_UNSPEC;
		net_sin(&addr)->sin_port = htons(port);
	}

	if (addr.family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		ret = setup_ipv6_ctx(ctx, &addr);
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr.family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		ret = setup_ipv4_ctx(ctx, &addr);
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr.family == AF_UNSPEC) {
#if defined(CONFIG_NET_IPV4)
		ret = setup_ipv4_ctx(ctx, &addr);
#endif
		/* We ignore the IPv4 error if IPv6 is enabled */
#if defined(CONFIG_NET_IPV6)
		memset(&addr, 0, sizeof(addr));
		addr.family = AF_UNSPEC;
		net_sin6(&addr)->sin6_port = htons(port);

		ret = setup_ipv6_ctx(ctx, &addr);
#endif
	} else {
		return -EINVAL;
	}

	return ret;
}

bool http_server_enable(struct http_server_ctx *http_ctx)
{
	bool old;

	NET_ASSERT(http_ctx);

	old = http_ctx->enabled;

	http_ctx->enabled = true;

#if defined(CONFIG_HTTPS)
	if (http_ctx->is_https) {
		https_enable(http_ctx);
	}
#endif
	return old;
}

bool http_server_disable(struct http_server_ctx *http_ctx)
{
	bool old;

	NET_ASSERT(http_ctx);

	req_timer_cancel(http_ctx);

	old = http_ctx->enabled;

	http_ctx->enabled = false;

#if defined(CONFIG_HTTPS)
	if (http_ctx->is_https) {
		https_disable(http_ctx);
	}
#endif
	return old;
}

int http_server_init(struct http_server_ctx *http_ctx,
		     struct http_server_urls *urls,
		     struct sockaddr *server_addr,
		     u8_t *request_buf,
		     size_t request_buf_len,
		     const char *server_banner)
{
	int ret;

	if (http_ctx->urls) {
		NET_ERR("Server context %p already initialized", http_ctx);
		return -EINVAL;
	}

	if (!request_buf || request_buf_len == 0) {
		NET_ERR("Request buf must be set");
		return -EINVAL;
	}

	ret = init_net(http_ctx, server_addr, HTTP_DEFAULT_PORT);
	if (ret < 0) {
		return ret;
	}

	if (server_banner) {
		new_server(http_ctx, server_banner, server_addr);
	}

	http_ctx->req.request_buf = request_buf;
	http_ctx->req.request_buf_len = request_buf_len;
	http_ctx->req.data_len = 0;
	http_ctx->urls = urls;
	http_ctx->recv_cb = http_recv;
	http_ctx->send_data = net_context_send;

	k_delayed_work_init(&http_ctx->req.timer, req_timeout);

	parser_init(http_ctx);

	return 0;
}

void http_server_release(struct http_server_ctx *http_ctx)
{
	if (!http_ctx->urls) {
		return;
	}

	http_server_disable(http_ctx);

#if defined(CONFIG_NET_IPV4)
	if (http_ctx->net_ipv4_ctx) {
		net_context_put(http_ctx->net_ipv4_ctx);
		http_ctx->net_ipv4_ctx = NULL;
	}
#endif
#if defined(CONFIG_NET_IPV6)
	if (http_ctx->net_ipv6_ctx) {
		net_context_put(http_ctx->net_ipv6_ctx);
		http_ctx->net_ipv6_ctx = NULL;
	}
#endif

	http_ctx->req.net_ctx = NULL;
	http_ctx->urls = NULL;
}

#if defined(CONFIG_HTTPS)
struct rx_fifo_block {
	sys_snode_t snode;
	struct k_mem_block block;
	struct net_pkt *pkt;
};

#if defined(MBEDTLS_DEBUG_C) && defined(CONFIG_NET_DEBUG_HTTP)
static void my_debug(void *ctx, int level,
		     const char *file, int line, const char *str)
{
	const char *p, *basename;
	int len;

	ARG_UNUSED(ctx);

	/* Extract basename from file */
	for (p = basename = file; *p != '\0'; p++) {
		if (*p == '/' || *p == '\\') {
			basename = p + 1;
		}

	}

	/* Avoid printing double newlines */
	len = strlen(str);
	if (str[len - 1] == '\n') {
		((char *)str)[len - 1] = '\0';
	}

	NET_DBG("%s:%04d: |%d| %s", basename, line, level, str);
}
#endif /* MBEDTLS_DEBUG_C && CONFIG_NET_DEBUG_HTTP */

#if defined(MBEDTLS_ERROR_C)
#define print_error(fmt, ret)						\
	do {								\
		char error[64];						\
									\
		mbedtls_strerror(ret, error, sizeof(error));		\
									\
		NET_ERR(fmt " (%s)", -ret, error);			\
	} while (0)
#else
#define print_error(fmt, ret)						\
	do {								\
		NET_ERR(fmt, -ret);					\
	} while (0)
#endif

#define BUF_ALLOC_TIMEOUT 100

/* Receive encrypted data from network. Put that data into fifo
 * that will be read by https thread.
 */
static void ssl_received(struct net_context *context,
			 struct net_pkt *pkt,
			 int status,
			 void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;
	struct rx_fifo_block *rx_data = NULL;
	struct k_mem_block block;
	int ret;

	ARG_UNUSED(context);
	ARG_UNUSED(status);

	if (pkt && !net_pkt_appdatalen(pkt)) {
		net_pkt_unref(pkt);
		return;
	}

	ret = k_mem_pool_alloc(http_ctx->https.pool, &block,
			       sizeof(struct rx_fifo_block),
			       BUF_ALLOC_TIMEOUT);
	if (ret < 0) {
		net_pkt_unref(pkt);
		return;
	}

	rx_data = block.data;
	rx_data->pkt = pkt;

	/* For freeing memory later */
	memcpy(&rx_data->block, &block, sizeof(struct k_mem_block));

	k_fifo_put(&http_ctx->https.mbedtls.ssl_ctx.rx_fifo, (void *)rx_data);
}

/* This will copy data from received net_pkt buf into mbedtls internal buffers.
 */
static int ssl_rx(void *context, unsigned char *buf, size_t size)
{
	struct http_server_ctx *ctx = context;
	struct rx_fifo_block *rx_data;
	u16_t read_bytes;
	u8_t *ptr;
	int pos;
	int len;
	int ret = 0;

	if (!ctx->https.mbedtls.ssl_ctx.frag) {
		rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo,
				     K_FOREVER);
		if (!rx_data->pkt) {
			NET_DBG("Closing %p connection", ctx);
			k_mem_pool_free(&rx_data->block);
			return -EIO;
		}

		ctx->https.mbedtls.ssl_ctx.rx_pkt = rx_data->pkt;

		k_mem_pool_free(&rx_data->block);

		read_bytes = net_pkt_appdatalen(
					ctx->https.mbedtls.ssl_ctx.rx_pkt);

		ctx->https.mbedtls.ssl_ctx.remaining = read_bytes;
		ctx->https.mbedtls.ssl_ctx.frag =
			ctx->https.mbedtls.ssl_ctx.rx_pkt->frags;

		ptr = net_pkt_appdata(ctx->https.mbedtls.ssl_ctx.rx_pkt);
		len = ptr - ctx->https.mbedtls.ssl_ctx.frag->data;

		if (len > ctx->https.mbedtls.ssl_ctx.frag->size) {
			NET_ERR("Buf overflow (%d > %u)", len,
				ctx->https.mbedtls.ssl_ctx.frag->size);
			return -EINVAL;
		} else {
			/* This will get rid of IP header */
			net_buf_pull(ctx->https.mbedtls.ssl_ctx.frag, len);
		}
	} else {
		read_bytes = ctx->https.mbedtls.ssl_ctx.remaining;
		ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
	}

	len = ctx->https.mbedtls.ssl_ctx.frag->len;
	pos = 0;
	if (read_bytes > size) {
		while (ctx->https.mbedtls.ssl_ctx.frag) {
			read_bytes = len < (size - pos) ? len : (size - pos);

#if RX_EXTRA_DEBUG == 1
			NET_DBG("Copying %d bytes", read_bytes);
#endif

			memcpy(buf + pos, ptr, read_bytes);

			pos += read_bytes;
			if (pos < size) {
				ctx->https.mbedtls.ssl_ctx.frag =
					ctx->https.mbedtls.ssl_ctx.frag->frags;
				ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
				len = ctx->https.mbedtls.ssl_ctx.frag->len;
			} else {
				if (read_bytes == len) {
					ctx->https.mbedtls.ssl_ctx.frag =
					ctx->https.mbedtls.ssl_ctx.frag->frags;
				} else {
					net_buf_pull(
					       ctx->https.mbedtls.ssl_ctx.frag,
					       read_bytes);
				}

				ctx->https.mbedtls.ssl_ctx.remaining -= size;
				return size;
			}
		}
	} else {
		while (ctx->https.mbedtls.ssl_ctx.frag) {
#if RX_EXTRA_DEBUG == 1
			NET_DBG("Copying all %d bytes", len);
#endif

			memcpy(buf + pos, ptr, len);

			pos += len;
			ctx->https.mbedtls.ssl_ctx.frag =
				ctx->https.mbedtls.ssl_ctx.frag->frags;
			if (!ctx->https.mbedtls.ssl_ctx.frag) {
				break;
			}

			ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
			len = ctx->https.mbedtls.ssl_ctx.frag->len;
		}

		net_pkt_unref(ctx->https.mbedtls.ssl_ctx.rx_pkt);
		ctx->https.mbedtls.ssl_ctx.rx_pkt = NULL;
		ctx->https.mbedtls.ssl_ctx.frag = NULL;
		ctx->https.mbedtls.ssl_ctx.remaining = 0;

		if (read_bytes != pos) {
			return -EIO;
		}

		ret = read_bytes;
	}

	return ret;
}

static void ssl_sent(struct net_context *context,
		     int status, void *token, void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;

	k_sem_give(&http_ctx->https.mbedtls.ssl_ctx.tx_sem);
}

/* Send encrypted data */
static int ssl_tx(void *context, const unsigned char *buf, size_t size)
{
	struct http_server_ctx *ctx = context;
	struct net_pkt *send_buf;
	int ret, len;

	send_buf = net_pkt_get_tx(ctx->req.net_ctx, BUF_ALLOC_TIMEOUT);
	if (!send_buf) {
		return MBEDTLS_ERR_SSL_ALLOC_FAILED;
	}

	ret = net_pkt_append_all(send_buf, size, (u8_t *)buf,
				 BUF_ALLOC_TIMEOUT);
	if (!ret) {
		/* Cannot append data */
		net_pkt_unref(send_buf);
		return 0;
	}

	len = size;

	ret = net_context_send(send_buf, ssl_sent, K_NO_WAIT, NULL, ctx);
	if (ret < 0) {
		net_pkt_unref(send_buf);
		return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
	}

	k_sem_take(&ctx->https.mbedtls.ssl_ctx.tx_sem, K_FOREVER);

	return len;
}

static int entropy_source(void *data, unsigned char *output, size_t len,
			  size_t *olen)
{
	u32_t seed;

	ARG_UNUSED(data);

	seed = sys_rand32_get();

	if (len > sizeof(seed)) {
		len = sizeof(seed);
	}

	memcpy(output, &seed, len);

	*olen = len;
	return 0;
}

/* This gets plain data and it sends encrypted one to peer */
static int https_send(struct net_pkt *pkt,
		      net_context_send_cb_t cb,
		      s32_t timeout,
		      void *token,
		      void *user_data)
{
	struct http_server_ctx *ctx = user_data;
	int ret;
	u16_t len;

	len = net_pkt_appdatalen(pkt);

	ret = net_frag_linearize(ctx->req.request_buf,
				 ctx->req.request_buf_len,
				 pkt, net_pkt_ip_hdr_len(pkt),
				 len);
	if (ret < 0) {
		NET_DBG("Cannot linearize send data (%d)", ret);
		return ret;
	}

	if (ret != len) {
		NET_DBG("Linear copy error (%u vs %d)", len, ret);
		return -EINVAL;
	}

	do {
		ret = mbedtls_ssl_write(&ctx->https.mbedtls.ssl,
					ctx->req.request_buf, len);
		if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
			print_error("peer closed the connection -0x%x", ret);
			goto out;
		}

		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret < 0) {
				print_error("mbedtls_ssl_write returned "
					    "-0x%x", ret);
				goto out;
			}
		}
	} while (ret <= 0);

out:
	if (cb) {
		cb(net_pkt_context(pkt), ret, token, user_data);
	}

	return ret;
}

static void https_handler(struct http_server_ctx *ctx)
{
	size_t len;
	int ret;

	NET_DBG("HTTPS handler starting");

	mbedtls_platform_set_printf(printk);

	http_heap_init();

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt_init(&ctx->https.mbedtls.srvcert);
#endif

	mbedtls_pk_init(&ctx->https.mbedtls.pkey);
	mbedtls_ssl_init(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_config_init(&ctx->https.mbedtls.conf);
	mbedtls_entropy_init(&ctx->https.mbedtls.entropy);
	mbedtls_ctr_drbg_init(&ctx->https.mbedtls.ctr_drbg);

#if defined(MBEDTLS_DEBUG_C) && defined(CONFIG_NET_DEBUG_HTTP)
	mbedtls_debug_set_threshold(DEBUG_THRESHOLD);
	mbedtls_ssl_conf_dbg(&ctx->https.mbedtls.conf, my_debug, NULL);
#endif

	/* Load the certificates and private RSA key. This needs to be done
	 * by the user so we call a callback that user must have provided.
	 */
	ret = ctx->https.mbedtls.cert_cb(ctx, &ctx->https.mbedtls.srvcert,
					 &ctx->https.mbedtls.pkey);
	if (ret != 0) {
		goto exit;
	}

	/* Seed the RNG */
	mbedtls_entropy_add_source(&ctx->https.mbedtls.entropy,
				   ctx->https.mbedtls.entropy_src_cb,
				   NULL,
				   MBEDTLS_ENTROPY_MAX_GATHER,
				   MBEDTLS_ENTROPY_SOURCE_STRONG);

	ret = mbedtls_ctr_drbg_seed(
		&ctx->https.mbedtls.ctr_drbg,
		mbedtls_entropy_func,
		&ctx->https.mbedtls.entropy,
		(const unsigned char *)ctx->https.mbedtls.personalization_data,
		ctx->https.mbedtls.personalization_data_len);
	if (ret != 0) {
		print_error("mbedtls_ctr_drbg_seed returned -0x%x", ret);
		goto exit;
	}

	/* Setup SSL defaults etc. */
	ret = mbedtls_ssl_config_defaults(&ctx->https.mbedtls.conf,
					  MBEDTLS_SSL_IS_SERVER,
					  MBEDTLS_SSL_TRANSPORT_STREAM,
					  MBEDTLS_SSL_PRESET_DEFAULT);
	if (ret != 0) {
		print_error("mbedtls_ssl_config_defaults returned -0x%x", ret);
		goto exit;
	}

	mbedtls_ssl_conf_rng(&ctx->https.mbedtls.conf,
			     mbedtls_ctr_drbg_random,
			     &ctx->https.mbedtls.ctr_drbg);

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_ssl_conf_ca_chain(&ctx->https.mbedtls.conf,
				  ctx->https.mbedtls.srvcert.next,
				  NULL);

	ret = mbedtls_ssl_conf_own_cert(&ctx->https.mbedtls.conf,
					&ctx->https.mbedtls.srvcert,
					&ctx->https.mbedtls.pkey);
	if (ret != 0) {
		print_error("mbedtls_ssl_conf_own_cert returned -0x%x", ret);
		goto exit;
	}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

	ret = mbedtls_ssl_setup(&ctx->https.mbedtls.ssl,
				&ctx->https.mbedtls.conf);
	if (ret != 0) {
		print_error("mbedtls_ssl_setup returned -0x%x", ret);
		goto exit;
	}

reset:
	mbedtls_ssl_session_reset(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_set_bio(&ctx->https.mbedtls.ssl, ctx, ssl_tx,
			    ssl_rx, NULL);

	/* SSL handshake. The ssl_rx() function will be called next by
	 * mbedtls library. The ssl_rx() will block and wait that data is
	 * received by ssl_received() and passed to it via fifo. After
	 * receiving the data, this function will then proceed with secure
	 * connection establishment.
	 */
	/* Waiting SSL handshake */
	do {
		ret = mbedtls_ssl_handshake(&ctx->https.mbedtls.ssl);
		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret < 0) {
				goto reset;
			}
		}
	} while (ret != 0);

	/* Read the HTTPS Request */
	NET_DBG("Read HTTPS request");
	do {
		len = ctx->req.request_buf_len - 1;
		memset(ctx->req.request_buf, 0, ctx->req.request_buf_len);

		ret = mbedtls_ssl_read(&ctx->https.mbedtls.ssl,
				       ctx->req.request_buf, len);
		if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
		    ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
			continue;
		}

		if (ret <= 0) {
			switch (ret) {
			case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
				NET_DBG("Connection was closed gracefully");
				goto close;

			case MBEDTLS_ERR_NET_CONN_RESET:
				NET_DBG("Connection was reset by peer");
				break;

			default:
				print_error("mbedtls_ssl_read returned "
					    "-0x%x", ret);
				break;
			}

			goto close;
		}

		ret = http_parser_execute(&ctx->req.parser,
					  &ctx->req.settings,
					  ctx->req.request_buf,
					  ret);
	} while (ret < 0);

	/* Write the Response */
	NET_DBG("Write HTTPS response");

	if (ctx->req.parser.http_errno != HPE_OK) {
		http_response_400(ctx, NULL);
	} else {
		http_process_recv(ctx);
	}

close:
	http_parser_init(&ctx->req.parser, HTTP_REQUEST);

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

	goto reset;

exit:
	return;
}

static void https_enable(struct http_server_ctx *ctx)
{
	/* Start the thread that handles HTTPS traffic. */
	if (ctx->https.tid) {
		return;
	}

	ctx->https.tid = k_thread_create(&ctx->https.thread,
					 ctx->https.stack,
					 ctx->https.stack_size,
					 (k_thread_entry_t)https_handler,
					 ctx, NULL, NULL,
					 K_PRIO_COOP(7), 0, 0);
}

static void https_disable(struct http_server_ctx *ctx)
{
	if (!ctx->https.tid) {
		return;
	}

	mbedtls_ssl_free(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_config_free(&ctx->https.mbedtls.conf);
	mbedtls_ctr_drbg_free(&ctx->https.mbedtls.ctr_drbg);
	mbedtls_entropy_free(&ctx->https.mbedtls.entropy);

	/* Empty the fifo just in case there is any received packets
	 * still there.
	 */
	while (1) {
		struct rx_fifo_block *rx_data;

		rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo,
				     K_NO_WAIT);
		if (!rx_data) {
			break;
		}

		net_pkt_unref(rx_data->pkt);

		k_mem_pool_free(&rx_data->block);
	}

	NET_DBG("HTTPS thread %p stopped", ctx->https.tid);

	k_thread_abort(ctx->https.tid);
	ctx->https.tid = 0;
}

static int https_init(struct http_server_ctx *ctx)
{
	k_sem_init(&ctx->https.mbedtls.ssl_ctx.tx_sem, 0, UINT_MAX);
	k_fifo_init(&ctx->https.mbedtls.ssl_ctx.rx_fifo);

	/* Next we return to application which must then enable the HTTPS
	 * service. The enable function will then start the https thread and
	 * do what ever further configuration needed.
	 *
	 * We do the mbedtls initialization in its own thread because it uses
	 * of of stack and the main stack runs out of memory very easily.
	 *
	 * See https_handler() how the things proceed from now on.
	 */

	return 0;
}

int https_server_init(struct http_server_ctx *ctx,
		      struct http_server_urls *urls,
		      struct sockaddr *server_addr,
		      u8_t *request_buf,
		      size_t request_buf_len,
		      const char *server_banner,
		      u8_t *personalization_data,
		      size_t personalization_data_len,
		      https_server_cert_cb_t cert_cb,
		      https_entropy_src_cb_t entropy_src_cb,
		      struct k_mem_pool *pool,
		      u8_t *https_stack,
		      size_t https_stack_size)
{
	int ret;

	if (ctx->urls) {
		NET_ERR("Server context %p already initialized", ctx);
		return -EALREADY;
	}

	if (!request_buf || request_buf_len == 0) {
		NET_ERR("Request buf must be set");
		return -EINVAL;
	}

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

	ret = init_net(ctx, server_addr, HTTPS_DEFAULT_PORT);
	if (ret < 0) {
		return ret;
	}

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

	ctx->req.request_buf = request_buf;
	ctx->req.request_buf_len = request_buf_len;
	ctx->req.data_len = 0;
	ctx->urls = urls;
	ctx->is_https = true;
	ctx->https.stack = https_stack;
	ctx->https.stack_size = https_stack_size;
	ctx->https.mbedtls.cert_cb = cert_cb;
	ctx->https.pool = pool;

	if (entropy_src_cb) {
		ctx->https.mbedtls.entropy_src_cb = entropy_src_cb;
	} else {
		ctx->https.mbedtls.entropy_src_cb = entropy_source;
	}

	ctx->https.mbedtls.personalization_data = personalization_data;
	ctx->https.mbedtls.personalization_data_len = personalization_data_len;
	ctx->send_data = https_send;
	ctx->recv_cb = ssl_received;

	k_delayed_work_init(&ctx->req.timer, req_timeout);

	parser_init(ctx);

	/* Then mbedtls specific initialization */
	return https_init(ctx);
}
#endif /* CONFIG_HTTPS */
