/*
 * 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/client"
#else
#define SYS_LOG_DOMAIN "http/client"
#endif
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

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

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

#include "../../ip/net_private.h"

#define BUF_ALLOC_TIMEOUT 100

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

#define HTTP_EOF           "\r\n\r\n"

#define HTTP_HOST          "Host"
#define HTTP_CONTENT_TYPE  "Content-Type"
#define HTTP_CONTENT_LEN   "Content-Length"
#define HTTP_CONT_LEN_SIZE 6

/* Default network activity timeout in seconds */
#define HTTP_NETWORK_TIMEOUT	K_SECONDS(CONFIG_HTTP_CLIENT_NETWORK_TIMEOUT)

int client_reset(struct http_ctx *ctx)
{
	http_parser_init(&ctx->http.parser, HTTP_RESPONSE);

	memset(ctx->http.rsp.http_status, 0,
	       sizeof(ctx->http.rsp.http_status));

	ctx->http.rsp.cl_present = 0;
	ctx->http.rsp.content_length = 0;
	ctx->http.rsp.processed = 0;
	ctx->http.rsp.body_found = 0;
	ctx->http.rsp.message_complete = 0;
	ctx->http.rsp.body_start = NULL;

	memset(ctx->http.rsp.response_buf, 0, ctx->http.rsp.response_buf_len);
	ctx->http.rsp.data_len = 0;

	return 0;
}

int http_request(struct http_ctx *ctx, struct http_request *req, s32_t timeout,
		 void *user_data)
{
	const char *method = http_method_str(req->method);
	int ret;

	if (ctx->pending) {
		net_pkt_unref(ctx->pending);
		ctx->pending = NULL;
	}

	ret = http_add_header(ctx, method, user_data);
	if (ret < 0) {
		goto out;
	}

	ret = http_add_header(ctx, " ", user_data);
	if (ret < 0) {
		goto out;
	}

	ret = http_add_header(ctx, req->url, user_data);
	if (ret < 0) {
		goto out;
	}

	ret = http_add_header(ctx, req->protocol, user_data);
	if (ret < 0) {
		goto out;
	}

	ret = http_add_header(ctx, HTTP_CRLF, user_data);
	if (ret < 0) {
		goto out;
	}

	if (req->host) {
		ret = http_add_header_field(ctx, HTTP_HOST, req->host,
					    user_data);
		if (ret < 0) {
			goto out;
		}
	}

	if (req->header_fields) {
		ret = http_add_header(ctx, req->header_fields, user_data);
		if (ret < 0) {
			goto out;
		}
	}

	if (req->content_type_value) {
		ret = http_add_header_field(ctx, HTTP_CONTENT_TYPE,
					    req->content_type_value,
					    user_data);
		if (ret < 0) {
			goto out;
		}
	}

	if (req->payload && req->payload_size) {
		char content_len_str[HTTP_CONT_LEN_SIZE];

		ret = snprintk(content_len_str, HTTP_CONT_LEN_SIZE,
			       "%u", req->payload_size);
		if (ret <= 0 || ret >= HTTP_CONT_LEN_SIZE) {
			ret = -ENOMEM;
			goto out;
		}

		ret = http_add_header_field(ctx, HTTP_CONTENT_LEN,
					    content_len_str, user_data);
		if (ret < 0) {
			goto out;
		}

		ret = http_add_header(ctx, HTTP_CRLF, user_data);
		if (ret < 0) {
			goto out;
		}

		ret = http_prepare_and_send(ctx, req->payload,
					    req->payload_size, user_data);
		if (ret < 0) {
			goto out;
		}
	} else {
		ret = http_add_header(ctx, HTTP_EOF, user_data);
		if (ret < 0) {
			goto out;
		}
	}

	http_send_flush(ctx, user_data);

out:
	if (ctx->pending) {
		net_pkt_unref(ctx->pending);
		ctx->pending = NULL;
	}

	return ret;
}

#if defined(CONFIG_NET_DEBUG_HTTP)
static void sprint_addr(char *buf, int len,
			sa_family_t family,
			struct sockaddr *addr)
{
	if (family == AF_INET6) {
		net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, buf, len);
	} else if (family == AF_INET) {
		net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, buf, len);
	} else {
		NET_DBG("Invalid protocol family");
	}
}
#endif

static inline void print_info(struct http_ctx *ctx,
			      enum http_method method)
{
#if defined(CONFIG_NET_DEBUG_HTTP)
	char local[NET_IPV6_ADDR_LEN];
	char remote[NET_IPV6_ADDR_LEN];

	sprint_addr(local, NET_IPV6_ADDR_LEN,
		    ctx->app_ctx.default_ctx->local.sa_family,
		    &ctx->app_ctx.default_ctx->local);

	sprint_addr(remote, NET_IPV6_ADDR_LEN,
		    ctx->app_ctx.default_ctx->remote.sa_family,
		    &ctx->app_ctx.default_ctx->remote);

	NET_DBG("HTTP %s (%s) %s -> %s port %d",
		http_method_str(method), ctx->http.req.host, local, remote,
		ntohs(net_sin(&ctx->app_ctx.default_ctx->remote)->sin_port));
#endif
}

int http_client_send_req(struct http_ctx *ctx,
			 struct http_request *req,
			 http_response_cb_t cb,
			 u8_t *response_buf,
			 size_t response_buf_len,
			 void *user_data,
			 s32_t timeout)
{
	int ret;

	if (!response_buf || response_buf_len == 0) {
		return -EINVAL;
	}

	ctx->http.rsp.response_buf = response_buf;
	ctx->http.rsp.response_buf_len = response_buf_len;

	client_reset(ctx);

	if (!req->host) {
		req->host = ctx->server;
	}

	ctx->http.req.host = req->host;
	ctx->http.req.method = req->method;
	ctx->http.req.user_data = user_data;

	ctx->http.rsp.cb = cb;

	ret = net_app_connect(&ctx->app_ctx, HTTP_NETWORK_TIMEOUT);
	if (ret < 0) {
		NET_DBG("Cannot connect to server (%d)", ret);
		return ret;
	}

	/* We might wait longer than timeout if the first connection
	 * establishment takes long time (like with HTTPS)
	 */
	if (k_sem_take(&ctx->http.connect_wait, HTTP_NETWORK_TIMEOUT)) {
		NET_DBG("Connection timed out");
		ret = -ETIMEDOUT;
		goto out;
	}

	print_info(ctx, ctx->http.req.method);

	ret = http_request(ctx, req, timeout, user_data);
	if (ret < 0) {
		NET_DBG("Send error (%d)", ret);
		goto out;
	}

	if (timeout != 0 && k_sem_take(&ctx->http.req.wait, timeout)) {
		ret = -ETIMEDOUT;
		goto out;
	}

	if (timeout == 0) {
		return -EINPROGRESS;
	}

	return 0;

out:
	return ret;
}

static void print_header_field(size_t len, const char *str)
{
#if defined(CONFIG_NET_DEBUG_HTTP)
#define MAX_OUTPUT_LEN 128
	char output[MAX_OUTPUT_LEN];

	/* The value of len does not count \0 so we need to increase it
	 * by one.
	 */
	if ((len + 1) > sizeof(output)) {
		len = sizeof(output) - 1;
	}

	snprintk(output, len + 1, "%s", str);

	NET_DBG("[%zd] %s", len, output);
#endif
}

static int on_url(struct http_parser *parser, const char *at, size_t length)
{
	ARG_UNUSED(parser);

	print_header_field(length, at);

	return 0;
}

static int on_status(struct http_parser *parser, const char *at, size_t length)
{
	u16_t len;
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	len = min(length, sizeof(ctx->http.rsp.http_status) - 1);
	memcpy(ctx->http.rsp.http_status, at, len);
	ctx->http.rsp.http_status[len] = 0;

	NET_DBG("HTTP response status %s", ctx->http.rsp.http_status);

	return 0;
}

static int on_header_field(struct http_parser *parser, const char *at,
			   size_t length)
{
	const char *content_len = HTTP_CONTENT_LEN;
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);
	u16_t len;

	len = strlen(content_len);
	if (length >= len && memcmp(at, content_len, len) == 0) {
		ctx->http.rsp.cl_present = true;
	}

	print_header_field(length, at);

	return 0;
}

#define MAX_NUM_DIGITS	16

static int on_header_value(struct http_parser *parser, const char *at,
			   size_t length)
{
	char str[MAX_NUM_DIGITS];
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	if (ctx->http.rsp.cl_present) {
		if (length <= MAX_NUM_DIGITS - 1) {
			long int num;

			memcpy(str, at, length);
			str[length] = 0;

			num = strtol(str, NULL, 10);
			if (num == LONG_MIN || num == LONG_MAX) {
				return -EINVAL;
			}

			ctx->http.rsp.content_length = num;
		}

		ctx->http.rsp.cl_present = false;
	}

	print_header_field(length, at);

	return 0;
}

static int on_body(struct http_parser *parser, const char *at, size_t length)
{
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	ctx->http.rsp.body_found = 1;
	ctx->http.rsp.processed += length;

	NET_DBG("Processed %zd length %zd", ctx->http.rsp.processed, length);

	if (!ctx->http.rsp.body_start &&
	    (u8_t *)at != (u8_t *)ctx->http.rsp.response_buf) {
		ctx->http.rsp.body_start = (u8_t *)at;
	}

	if (ctx->http.rsp.cb) {
		NET_DBG("Calling callback for partitioned %zd len data",
			ctx->http.rsp.data_len);

		ctx->http.rsp.cb(ctx,
				 ctx->http.rsp.response_buf,
				 ctx->http.rsp.response_buf_len,
				 ctx->http.rsp.data_len,
				 HTTP_DATA_MORE,
				 ctx->http.req.user_data);

		/* Re-use the result buffer and start to fill it again */
		ctx->http.rsp.data_len = 0;
		ctx->http.rsp.body_start = NULL;
	}

	return 0;
}

static int on_headers_complete(struct http_parser *parser)
{
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	if (parser->status_code >= 500 && parser->status_code < 600) {
		NET_DBG("Status %d, skipping body", parser->status_code);

		return 1;
	}

	if ((ctx->http.req.method == HTTP_HEAD ||
	     ctx->http.req.method == HTTP_OPTIONS)
	    && ctx->http.rsp.content_length > 0) {
		NET_DBG("No body expected");
		return 1;
	}

	if ((ctx->http.req.method == HTTP_PUT ||
	     ctx->http.req.method == HTTP_POST)
	    && ctx->http.rsp.content_length == 0) {
		NET_DBG("No body expected");
		return 1;
	}

	NET_DBG("Headers complete");

	return 0;
}

static int on_message_begin(struct http_parser *parser)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	NET_DBG("-- HTTP %s response (headers) --",
		http_method_str(ctx->http.req.method));
#else
	ARG_UNUSED(parser);
#endif
	return 0;
}

static int on_message_complete(struct http_parser *parser)
{
	struct http_ctx *ctx = CONTAINER_OF(parser,
					    struct http_ctx,
					    http.parser);

	NET_DBG("-- HTTP %s response (complete) --",
		http_method_str(ctx->http.req.method));

	if (ctx->http.rsp.cb) {
		ctx->http.rsp.cb(ctx,
				 ctx->http.rsp.response_buf,
				 ctx->http.rsp.response_buf_len,
				 ctx->http.rsp.data_len,
				 HTTP_DATA_FINAL,
				 ctx->http.req.user_data);
	}

	ctx->http.rsp.message_complete = 1;

	k_sem_give(&ctx->http.req.wait);

	return 0;
}

static int on_chunk_header(struct http_parser *parser)
{
	ARG_UNUSED(parser);

	return 0;
}

static int on_chunk_complete(struct http_parser *parser)
{
	ARG_UNUSED(parser);

	return 0;
}

static void http_received(struct net_app_ctx *app_ctx,
			  struct net_pkt *pkt,
			  int status,
			  void *user_data)
{
	struct http_ctx *ctx = user_data;
	size_t start = ctx->http.rsp.data_len;
	u16_t len = 0;
	struct net_buf *frag, *prev_frag = NULL;
	size_t recv_len;
	size_t pkt_len;

	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("[%p] Status %d <%s>", ctx, status, RC_STR(status));
		goto out;
	}

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

	pkt_len = net_pkt_get_len(pkt);

	if (recv_len < pkt_len) {
		net_buf_pull(frag, pkt_len - recv_len);
		net_pkt_set_appdata(pkt, frag->data);
	}

	NET_DBG("[%p] Received %zd bytes http data", ctx, recv_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 ((ctx->http.rsp.data_len + frag->len) >
		    ctx->http.rsp.response_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 (!ctx->cb.recv) {
				ctx->http.rsp.data_len = recv_len;
				goto out;
			}

			http_parser_execute(&ctx->http.parser,
					    &ctx->http.parser_settings,
					    ctx->http.rsp.response_buf + start,
					    len);

			ctx->http.rsp.data_len = 0;
			len = 0;
			start = 0;
		}

		memcpy(ctx->http.rsp.response_buf + ctx->http.rsp.data_len,
		       frag->data, frag->len);

		ctx->http.rsp.data_len += frag->len;
		len += frag->len;

		prev_frag = frag;
		frag = frag->frags;
		pkt->frags = frag;

		prev_frag->frags = NULL;
		net_pkt_frag_unref(prev_frag);
	}

out:
	http_parser_execute(&ctx->http.parser,
			    &ctx->http.parser_settings,
			    ctx->http.rsp.response_buf + start,
			    len);

	net_pkt_unref(pkt);
	return;

quit:
	http_parser_init(&ctx->http.parser, HTTP_RESPONSE);
	ctx->http.rsp.data_len = 0;
	net_pkt_unref(pkt);
}

static void http_data_sent(struct net_app_ctx *app_ctx,
			   int status,
			   void *user_data_send,
			   void *user_data)
{
	struct http_ctx *ctx = user_data;

	if (!user_data_send) {
		/* This is the token field in the net_context_send().
		 * If this is not set, then it is TCP ACK messages
		 * that are generated by the stack. We just ignore those.
		 */
		return;
	}

	if (ctx->cb.send) {
		ctx->cb.send(ctx, status, user_data_send, ctx->user_data);
	}
}

static void http_connected(struct net_app_ctx *app_ctx,
			   int status,
			   void *user_data)
{
	struct http_ctx *ctx = user_data;

	if (status < 0) {
		return;
	}

	if (ctx->cb.connect) {
		ctx->cb.connect(ctx, HTTP_CONNECTION, ctx->user_data);
	}

	if (ctx->is_connected) {
		return;
	}

	ctx->is_connected = true;

	k_sem_give(&ctx->http.connect_wait);
}

static void http_closed(struct net_app_ctx *app_ctx,
			int status,
			void *user_data)
{
	struct http_ctx *ctx = user_data;

	ARG_UNUSED(app_ctx);
	ARG_UNUSED(status);

	NET_DBG("[%p] connection closed", ctx);

	ctx->is_connected = false;

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

int http_client_init(struct http_ctx *ctx,
		     const char *server,
		     u16_t server_port,
		     struct sockaddr *server_addr,
		     s32_t timeout)
{
	int ret;

	memset(ctx, 0, sizeof(*ctx));

	ret = net_app_init_tcp_client(&ctx->app_ctx,
				      NULL,         /* use any local address */
				      server_addr,
				      server,
				      server_port,
				      timeout,
				      ctx);
	if (ret < 0) {
		NET_DBG("Cannot init HTTP client (%d)", ret);
		return ret;
	}

	ret = net_app_set_cb(&ctx->app_ctx, http_connected, http_received,
			     http_data_sent, http_closed);
	if (ret < 0) {
		NET_ERR("Cannot set callbacks (%d)", ret);
		return ret;
	}

	ctx->http.parser_settings.on_body = on_body;
	ctx->http.parser_settings.on_chunk_complete = on_chunk_complete;
	ctx->http.parser_settings.on_chunk_header = on_chunk_header;
	ctx->http.parser_settings.on_headers_complete = on_headers_complete;
	ctx->http.parser_settings.on_header_field = on_header_field;
	ctx->http.parser_settings.on_header_value = on_header_value;
	ctx->http.parser_settings.on_message_begin = on_message_begin;
	ctx->http.parser_settings.on_message_complete = on_message_complete;
	ctx->http.parser_settings.on_status = on_status;
	ctx->http.parser_settings.on_url = on_url;

	k_sem_init(&ctx->http.req.wait, 0, 1);
	k_sem_init(&ctx->http.connect_wait, 0, 1);

	ctx->server = server;
	ctx->is_init = true;
	ctx->is_client = true;

	return 0;
}

int http_request_cancel(struct http_ctx *ctx)
{
	if (!ctx->is_init) {
		return -EINVAL;
	}

	if (!ctx->is_client) {
		return -EINVAL;
	}

	client_reset(ctx);

	return 0;
}

#if defined(CONFIG_HTTPS)
int http_client_set_tls(struct http_ctx *ctx,
			u8_t *request_buf,
			size_t request_buf_len,
			u8_t *personalization_data,
			size_t personalization_data_len,
			net_app_ca_cert_cb_t cert_cb,
			const char *cert_host,
			net_app_entropy_src_cb_t entropy_src_cb,
			struct k_mem_pool *pool,
			k_thread_stack_t *https_stack,
			size_t https_stack_size)
{
	int ret;

	ret = net_app_client_tls(&ctx->app_ctx,
				 request_buf,
				 request_buf_len,
				 personalization_data,
				 personalization_data_len,
				 cert_cb,
				 cert_host,
				 entropy_src_cb,
				 pool,
				 https_stack,
				 https_stack_size);
	if (ret < 0) {
		NET_DBG("Cannot init TLS (%d)", ret);
		return ret;
	}

	ctx->is_tls = true;

	return 0;
}
#endif /* CONFIG_HTTPS */
