/** @file
 * @brief HTTP client API
 *
 * An API for applications to send HTTP requests
 */

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

#include <logging/log.h>
LOG_MODULE_REGISTER(net_http, CONFIG_NET_HTTP_LOG_LEVEL);

#include <kernel.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>

#include <net/net_ip.h>
#include <net/socket.h>
#include <net/http_client.h>

#include "net_private.h"

#define HTTP_CONTENT_LEN_SIZE 6
#define MAX_SEND_BUF_LEN 192

static ssize_t sendall(int sock, const void *buf, size_t len)
{
	while (len) {
		ssize_t out_len = send(sock, buf, len, 0);

		if (out_len < 0) {
			return -errno;
		}

		buf = (const char *)buf + out_len;
		len -= out_len;
	}

	return 0;
}

static int http_send_data(int sock, char *send_buf,
			  size_t send_buf_max_len, size_t *send_buf_pos,
			  ...)
{
	const char *data;
	va_list va;
	int ret, end_of_send = *send_buf_pos;
	int end_of_data, remaining_len;

	va_start(va, send_buf_pos);

	data = va_arg(va, const char *);

	while (data) {
		end_of_data = 0;

		do {
			int to_be_copied;

			remaining_len = strlen(data + end_of_data);
			to_be_copied = send_buf_max_len - end_of_send;

			if (remaining_len > to_be_copied) {
				strncpy(send_buf + end_of_send,
					data + end_of_data,
					to_be_copied);

				end_of_send += to_be_copied;
				end_of_data += to_be_copied;
				remaining_len -= to_be_copied;

				LOG_HEXDUMP_DBG(send_buf, end_of_send,
						"Data to send");

				ret = sendall(sock, send_buf, end_of_send);
				if (ret < 0) {
					NET_DBG("Cannot send %d bytes (%d)",
						end_of_send, ret);
					goto err;
				}

				end_of_send = 0;
				continue;
			} else {
				strncpy(send_buf + end_of_send,
					data + end_of_data,
					remaining_len);
				end_of_send += remaining_len;
				remaining_len = 0;
			}
		} while (remaining_len > 0);

		data = va_arg(va, const char *);
	}

	va_end(va);

	if (end_of_send > (int)send_buf_max_len) {
		NET_ERR("Sending overflow (%d > %zd)", end_of_send,
			send_buf_max_len);
		return -EMSGSIZE;
	}

	*send_buf_pos = end_of_send;

	return end_of_send;

err:
	va_end(va);

	return ret;
}

static int http_flush_data(int sock, const char *send_buf, size_t send_buf_len)
{
	LOG_HEXDUMP_DBG(send_buf, send_buf_len, "Data to send");

	return sendall(sock, send_buf, send_buf_len);
}

static void print_header_field(size_t len, const char *str)
{
	if (IS_ENABLED(CONFIG_NET_HTTP_LOG_LEVEL_DBG)) {
#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, log_strdup(output));
	}
}

static int on_url(struct http_parser *parser, const char *at, size_t length)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);
	print_header_field(length, at);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_url) {
		req->internal.response.http_cb->on_url(parser, at, length);
	}

	return 0;
}

static int on_status(struct http_parser *parser, const char *at, size_t length)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);
	uint16_t len;

	len = MIN(length, sizeof(req->internal.response.http_status) - 1);
	memcpy(req->internal.response.http_status, at, len);
	req->internal.response.http_status[len] = 0;
	req->internal.response.http_status_code =
		(uint16_t)parser->status_code;

	NET_DBG("HTTP response status %d %s", parser->status_code,
		log_strdup(req->internal.response.http_status));

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_status) {
		req->internal.response.http_cb->on_status(parser, at, length);
	}

	return 0;
}

static int on_header_field(struct http_parser *parser, const char *at,
			   size_t length)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);
	const char *content_len = "Content-Length";
	uint16_t len;

	len = strlen(content_len);
	if (length >= len && strncasecmp(at, content_len, len) == 0) {
		req->internal.response.cl_present = true;
	}

	print_header_field(length, at);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_header_field) {
		req->internal.response.http_cb->on_header_field(parser, at,
								length);
	}

	return 0;
}

#define MAX_NUM_DIGITS	16

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

	if (req->internal.response.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;
			}

			req->internal.response.content_length = num;
		}

		req->internal.response.cl_present = false;
	}

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_header_value) {
		req->internal.response.http_cb->on_header_value(parser, at,
								length);
	}

	print_header_field(length, at);

	return 0;
}

static int on_body(struct http_parser *parser, const char *at, size_t length)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	req->internal.response.body_found = 1;
	req->internal.response.processed += length;

	NET_DBG("Processed %zd length %zd", req->internal.response.processed,
		length);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_body) {
		req->internal.response.http_cb->on_body(parser, at, length);
	}

	if (!req->internal.response.body_start &&
	    (uint8_t *)at != (uint8_t *)req->internal.response.recv_buf) {
		req->internal.response.body_start = (uint8_t *)at;
	}

	if (req->internal.response.cb) {
		if (http_should_keep_alive(parser)) {
			NET_DBG("Calling callback for partitioned %zd len data",
				req->internal.response.data_len);

			req->internal.response.cb(&req->internal.response,
						  HTTP_DATA_MORE,
						  req->internal.user_data);
		} else {
			NET_DBG("Calling callback for %zd len data",
				req->internal.response.data_len);

			req->internal.response.cb(&req->internal.response,
						  HTTP_DATA_FINAL,
						  req->internal.user_data);
		}

		/* Re-use the result buffer and start to fill it again */
		req->internal.response.data_len = 0;
		req->internal.response.body_start = NULL;
	}

	return 0;
}

static int on_headers_complete(struct http_parser *parser)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_headers_complete) {
		req->internal.response.http_cb->on_headers_complete(parser);
	}

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

	if ((req->method == HTTP_HEAD || req->method == HTTP_OPTIONS) &&
	    req->internal.response.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)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_message_begin) {
		req->internal.response.http_cb->on_message_begin(parser);
	}

	NET_DBG("-- HTTP %s response (headers) --",
		http_method_str(req->method));

	return 0;
}

static int on_message_complete(struct http_parser *parser)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_message_complete) {
		req->internal.response.http_cb->on_message_complete(parser);
	}

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

	req->internal.response.message_complete = 1;

	if (req->internal.response.cb) {
		req->internal.response.cb(&req->internal.response,
					  HTTP_DATA_FINAL,
					  req->internal.user_data);
	}

	return 0;
}

static int on_chunk_header(struct http_parser *parser)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_chunk_header) {
		req->internal.response.http_cb->on_chunk_header(parser);
	}

	return 0;
}

static int on_chunk_complete(struct http_parser *parser)
{
	struct http_request *req = CONTAINER_OF(parser,
						struct http_request,
						internal.parser);

	if (req->internal.response.http_cb &&
	    req->internal.response.http_cb->on_chunk_complete) {
		req->internal.response.http_cb->on_chunk_complete(parser);
	}

	return 0;
}

static void http_client_init_parser(struct http_parser *parser,
				    struct http_parser_settings *settings)
{
	http_parser_init(parser, HTTP_RESPONSE);

	settings->on_body = on_body;
	settings->on_chunk_complete = on_chunk_complete;
	settings->on_chunk_header = on_chunk_header;
	settings->on_headers_complete = on_headers_complete;
	settings->on_header_field = on_header_field;
	settings->on_header_value = on_header_value;
	settings->on_message_begin = on_message_begin;
	settings->on_message_complete = on_message_complete;
	settings->on_status = on_status;
	settings->on_url = on_url;
}

static int http_wait_data(int sock, struct http_request *req)
{
	int total_received = 0;
	size_t offset = 0;
	int received, ret;

	do {
		received = recv(sock, req->internal.response.recv_buf + offset,
				req->internal.response.recv_buf_len - offset,
				0);
		if (received == 0) {
			/* Connection closed */
			LOG_DBG("Connection closed");
			ret = total_received;
			break;
		} else if (received < 0) {
			/* Socket error */
			LOG_DBG("Connection error (%d)", errno);
			ret = -errno;
			break;
		} else {
			req->internal.response.data_len += received;

			(void)http_parser_execute(
				&req->internal.parser,
				&req->internal.parser_settings,
				req->internal.response.recv_buf + offset,
				received);
		}

		total_received += received;
		offset += received;

		if (offset >= req->internal.response.recv_buf_len) {
			offset = 0;
		}

		if (req->internal.response.message_complete) {
			ret = total_received;
			break;
		}

	} while (true);

	return ret;
}

static void http_timeout(struct k_work *work)
{
	struct http_client_internal_data *data =
		CONTAINER_OF(work, struct http_client_internal_data, work);

	(void)close(data->sock);
}

int http_client_req(int sock, struct http_request *req,
		    int32_t timeout, void *user_data)
{
	/* Utilize the network usage by sending data in bigger blocks */
	char send_buf[MAX_SEND_BUF_LEN];
	const size_t send_buf_max_len = sizeof(send_buf);
	size_t send_buf_pos = 0;
	int total_sent = 0;
	int ret, total_recv, i;
	const char *method;

	if (sock < 0 || req == NULL || req->response == NULL ||
	    req->recv_buf == NULL || req->recv_buf_len == 0) {
		return -EINVAL;
	}

	memset(&req->internal.response, 0, sizeof(req->internal.response));

	req->internal.response.http_cb = req->http_cb;
	req->internal.response.cb = req->response;
	req->internal.response.recv_buf = req->recv_buf;
	req->internal.response.recv_buf_len = req->recv_buf_len;
	req->internal.user_data = user_data;
	req->internal.sock = sock;
	req->internal.timeout = SYS_TIMEOUT_MS(timeout);

	method = http_method_str(req->method);

	ret = http_send_data(sock, send_buf, send_buf_max_len, &send_buf_pos,
			     method, " ", req->url, " ", req->protocol,
			     HTTP_CRLF, NULL);
	if (ret < 0) {
		goto out;
	}

	total_sent += ret;

	if (req->port) {
		ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, "Host", ": ", req->host,
				     ":", req->port, HTTP_CRLF, NULL);

		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	} else {
		ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, "Host", ": ", req->host,
				     HTTP_CRLF, NULL);

		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	}

	if (req->optional_headers_cb) {
		ret = http_flush_data(sock, send_buf, send_buf_pos);
		if (ret < 0) {
			goto out;
		}

		send_buf_pos = 0;
		total_sent += ret;

		ret = req->optional_headers_cb(sock, req, user_data);
		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	} else {
		for (i = 0; req->optional_headers && req->optional_headers[i];
		     i++) {
			ret = http_send_data(sock, send_buf, send_buf_max_len,
					     &send_buf_pos,
					     req->optional_headers[i], NULL);
			if (ret < 0) {
				goto out;
			}

			total_sent += ret;
		}
	}

	for (i = 0; req->header_fields && req->header_fields[i]; i++) {
		ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, req->header_fields[i],
				     NULL);
		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	}

	if (req->content_type_value) {
		ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, "Content-Type", ": ",
				     req->content_type_value, HTTP_CRLF, NULL);
		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	}

	if (req->payload || req->payload_cb) {
		if (req->payload_len) {
			char content_len_str[HTTP_CONTENT_LEN_SIZE];

			ret = snprintk(content_len_str, HTTP_CONTENT_LEN_SIZE,
				       "%zd", req->payload_len);
			if (ret <= 0 || ret >= HTTP_CONTENT_LEN_SIZE) {
				ret = -ENOMEM;
				goto out;
			}

			ret = http_send_data(sock, send_buf, send_buf_max_len,
					     &send_buf_pos, "Content-Length", ": ",
					     content_len_str, HTTP_CRLF,
					     HTTP_CRLF, NULL);
		} else {
			ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, HTTP_CRLF, NULL);
		}

		if (ret < 0) {
			goto out;
		}

		total_sent += ret;

		ret = http_flush_data(sock, send_buf, send_buf_pos);
		if (ret < 0) {
			goto out;
		}

		send_buf_pos = 0;
		total_sent += ret;

		if (req->payload_cb) {
			ret = req->payload_cb(sock, req, user_data);
			if (ret < 0) {
				goto out;
			}

			total_sent += ret;
		} else {
			uint32_t length;

			if (req->payload_len == 0) {
				length = strlen(req->payload);
			} else {
				length = req->payload_len;
			}

			ret = sendall(sock, req->payload, length);
			if (ret < 0) {
				goto out;
			}

			total_sent += length;
		}
	} else {
		ret = http_send_data(sock, send_buf, send_buf_max_len,
				     &send_buf_pos, HTTP_CRLF, NULL);
		if (ret < 0) {
			goto out;
		}
	}

	if (send_buf_pos > 0) {
		ret = http_flush_data(sock, send_buf, send_buf_pos);
		if (ret < 0) {
			goto out;
		}

		total_sent += ret;
	}

	NET_DBG("Sent %d bytes", total_sent);

	http_client_init_parser(&req->internal.parser,
				&req->internal.parser_settings);

	if (!K_TIMEOUT_EQ(req->internal.timeout, K_FOREVER) &&
	    !K_TIMEOUT_EQ(req->internal.timeout, K_NO_WAIT)) {
		k_work_init_delayable(&req->internal.work, http_timeout);
		(void)k_work_reschedule(&req->internal.work,
					req->internal.timeout);
	}

	/* Request is sent, now wait data to be received */
	total_recv = http_wait_data(sock, req);
	if (total_recv < 0) {
		NET_DBG("Wait data failure (%d)", total_recv);
	} else {
		NET_DBG("Received %d bytes", total_recv);
	}

	if (!K_TIMEOUT_EQ(req->internal.timeout, K_FOREVER) &&
	    !K_TIMEOUT_EQ(req->internal.timeout, K_NO_WAIT)) {
		(void)k_work_cancel_delayable(&req->internal.work);
	}

	return total_sent;

out:
	return ret;
}
