/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2018-2019 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_MODULE_NAME net_lwm2m_obj_firmware_pull
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL

#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <ctype.h>
#include <stdio.h>
#include <string.h>

#include <net/http_parser.h>
#include <net/socket.h>

#include "lwm2m_object.h"
#include "lwm2m_engine.h"

#define URI_LEN		255

#define NETWORK_INIT_TIMEOUT	K_SECONDS(10)
#define NETWORK_CONNECT_TIMEOUT	K_SECONDS(10)
#define PACKET_TRANSFER_RETRY_MAX	3

static char firmware_uri[URI_LEN];
static struct lwm2m_ctx firmware_ctx = {
	.sock_fd = -1
};
static int firmware_retry;
static struct coap_block_context firmware_block_ctx;

#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT)
#define COAP2COAP_PROXY_URI_PATH	"coap2coap"
#define COAP2HTTP_PROXY_URI_PATH	"coap2http"

static char proxy_uri[URI_LEN];
#endif

static void do_transmit_timeout_cb(struct lwm2m_message *msg);

static void set_update_result_from_error(int error_code)
{
	if (error_code == -ENOMEM) {
		lwm2m_firmware_set_update_result(RESULT_OUT_OF_MEM);
	} else if (error_code == -ENOSPC) {
		lwm2m_firmware_set_update_result(RESULT_NO_STORAGE);
	} else if (error_code == -EFAULT) {
		lwm2m_firmware_set_update_result(RESULT_INTEGRITY_FAILED);
	} else if (error_code == -ENOMSG) {
		lwm2m_firmware_set_update_result(RESULT_CONNECTION_LOST);
	} else if (error_code == -ENOTSUP) {
		lwm2m_firmware_set_update_result(RESULT_INVALID_URI);
	} else if (error_code == -EPROTONOSUPPORT) {
		lwm2m_firmware_set_update_result(RESULT_UNSUP_PROTO);
	} else {
		lwm2m_firmware_set_update_result(RESULT_UPDATE_FAILED);
	}
}

static int transfer_request(struct coap_block_context *ctx,
			    uint8_t *token, uint8_t tkl,
			    coap_reply_t reply_cb)
{
	struct lwm2m_message *msg;
	int ret;
	char *cursor;
#if !defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT)
	struct http_parser_url parser;
	uint16_t off, len;
	char *next_slash;
#endif

	msg = lwm2m_get_message(&firmware_ctx);
	if (!msg) {
		LOG_ERR("Unable to get a lwm2m message!");
		return -ENOMEM;
	}

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_GET;
	msg->mid = coap_next_id();
	msg->token = token;
	msg->tkl = tkl;
	msg->reply_cb = reply_cb;
	msg->message_timeout_cb = do_transmit_timeout_cb;

	ret = lwm2m_init_message(msg);
	if (ret < 0) {
		LOG_ERR("Error setting up lwm2m message");
		goto cleanup;
	}

#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT)
	/* TODO: shift to lower case */
	if (strncmp(firmware_uri, "http", 4) == 0) {
		cursor = COAP2HTTP_PROXY_URI_PATH;
	} else if (strncmp(firmware_uri, "coap", 4) == 0) {
		cursor = COAP2COAP_PROXY_URI_PATH;
	} else {
		ret = -EPROTONOSUPPORT;
		LOG_ERR("Unsupported schema");
		goto cleanup;
	}

	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					cursor, strlen(cursor));
	if (ret < 0) {
		LOG_ERR("Error adding URI_PATH '%s'", log_strdup(cursor));
		goto cleanup;
	}
#else
	http_parser_url_init(&parser);
	ret = http_parser_parse_url(firmware_uri, strlen(firmware_uri), 0,
				    &parser);
	if (ret < 0) {
		LOG_ERR("Invalid firmware url: %s", log_strdup(firmware_uri));
		ret = -ENOTSUP;
		goto cleanup;
	}

	/* if path is not available, off/len will be zero */
	off = parser.field_data[UF_PATH].off;
	len = parser.field_data[UF_PATH].len;
	cursor = firmware_uri + off;

	/* add path portions (separated by slashes) */
	while (len > 0 && (next_slash = strchr(cursor, '/')) != NULL) {
		if (next_slash != cursor) {
			ret = coap_packet_append_option(&msg->cpkt,
							COAP_OPTION_URI_PATH,
							cursor,
							next_slash - cursor);
			if (ret < 0) {
				LOG_ERR("Error adding URI_PATH");
				goto cleanup;
			}
		}

		/* skip slash */
		len -= (next_slash - cursor) + 1;
		cursor = next_slash + 1;
	}

	if (len > 0) {
		/* flush the rest */
		ret = coap_packet_append_option(&msg->cpkt,
						COAP_OPTION_URI_PATH,
						cursor, len);
		if (ret < 0) {
			LOG_ERR("Error adding URI_PATH");
			goto cleanup;
		}
	}
#endif

	ret = coap_append_block2_option(&msg->cpkt, ctx);
	if (ret < 0) {
		LOG_ERR("Unable to add block2 option.");
		goto cleanup;
	}

#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT)
	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_PROXY_URI,
					firmware_uri, strlen(firmware_uri));
	if (ret < 0) {
		LOG_ERR("Error adding PROXY_URI '%s'",
			log_strdup(firmware_uri));
		goto cleanup;
	}
#else
	/* Ask the server to provide a size estimate */
	ret = coap_append_option_int(&msg->cpkt, COAP_OPTION_SIZE2, 0);
	if (ret < 0) {
		LOG_ERR("Unable to add size2 option.");
		goto cleanup;
	}
#endif

	/* send request */
	ret = lwm2m_send_message_async(msg);
	if (ret < 0) {
		LOG_ERR("Error sending LWM2M packet (err:%d).", ret);
		goto cleanup;
	}

	return 0;

cleanup:
	lwm2m_reset_message(msg, true);
	return ret;
}

static int
do_firmware_transfer_reply_cb(const struct coap_packet *response,
			      struct coap_reply *reply,
			      const struct sockaddr *from)
{
	int ret;
	bool last_block;
	uint8_t token[8];
	uint8_t tkl;
	uint16_t payload_len, payload_offset, len;
	struct coap_packet *check_response = (struct coap_packet *)response;
	struct lwm2m_engine_res *res = NULL;
	lwm2m_engine_set_data_cb_t write_cb;
	size_t write_buflen;
	uint8_t resp_code, *write_buf;
	struct coap_block_context received_block_ctx;
	const uint8_t *payload_start;

	/* token is used to determine a valid ACK vs a separated response */
	tkl = coap_header_get_token(check_response, token);

	/* If separated response (ACK) return and wait for response */
	if (!tkl && coap_header_get_type(response) == COAP_TYPE_ACK) {
		return 0;
	} else if (coap_header_get_type(response) == COAP_TYPE_CON) {
		/* Send back ACK so the server knows we received the pkt */
		ret = lwm2m_send_empty_ack(&firmware_ctx,
					   coap_header_get_id(check_response));
		if (ret < 0) {
			LOG_ERR("Error transmitting ACK");
			goto error;
		}
	}

	/* Check response code from server. Expecting (2.05) */
	resp_code = coap_header_get_code(check_response);
	if (resp_code != COAP_RESPONSE_CODE_CONTENT) {
		LOG_ERR("Unexpected response from server: %d.%d",
			COAP_RESPONSE_CODE_CLASS(resp_code),
			COAP_RESPONSE_CODE_DETAIL(resp_code));
		ret = -ENOMSG;
		goto error;
	}

	/* save main firmware block context */
	memcpy(&received_block_ctx, &firmware_block_ctx,
	       sizeof(firmware_block_ctx));

	ret = coap_update_from_block(check_response, &firmware_block_ctx);
	if (ret < 0) {
		LOG_ERR("Error from block update: %d", ret);
		ret = -EFAULT;
		goto error;
	}

	/* test for duplicate transfer */
	if (firmware_block_ctx.current < received_block_ctx.current) {
		LOG_WRN("Duplicate packet ignored");

		/* restore main firmware block context */
		memcpy(&firmware_block_ctx, &received_block_ctx,
		       sizeof(firmware_block_ctx));

		/* set reply->user_data to error to avoid releasing */
		reply->user_data = (void *)COAP_REPLY_STATUS_ERROR;
		return 0;
	}

	/* Reach last block if ret equals to 0 */
	last_block = !coap_next_block(check_response, &firmware_block_ctx);

	/* Process incoming data */
	payload_start = coap_packet_get_payload(response, &payload_len);
	if (payload_len > 0) {
		payload_offset = payload_start - response->data;
		LOG_DBG("total: %zd, current: %zd",
			firmware_block_ctx.total_size,
			firmware_block_ctx.current);

		/* look up firmware package resource */
		ret = lwm2m_engine_get_resource("5/0/0", &res);
		if (ret < 0) {
			goto error;
		}

		/* get buffer data */
		write_buf = res->res_instances->data_ptr;
		write_buflen = res->res_instances->max_data_len;

		/* check for user override to buffer */
		if (res->pre_write_cb) {
			write_buf = res->pre_write_cb(0, 0, 0, &write_buflen);
		}

		write_cb = lwm2m_firmware_get_write_cb();
		if (write_cb) {
			/* flush incoming data to write_cb */
			while (payload_len > 0) {
				len = (payload_len > write_buflen) ?
				       write_buflen : payload_len;
				payload_len -= len;
				/* check for end of packet */
				if (buf_read(write_buf, len,
					     CPKT_BUF_READ(response),
					     &payload_offset) < 0) {
					/* malformed packet */
					ret = -EFAULT;
					goto error;
				}

				ret = write_cb(0, 0, 0,
					       write_buf, len,
					       last_block &&
							(payload_len == 0U),
					       firmware_block_ctx.total_size);
				if (ret < 0) {
					goto error;
				}
			}
		}
	}

	if (!last_block) {
		/* More block(s) to come, setup next transfer */
		ret = transfer_request(&firmware_block_ctx, token, tkl,
				       do_firmware_transfer_reply_cb);
		if (ret < 0) {
			goto error;
		}
	} else {
		/* Download finished */
		lwm2m_firmware_set_update_state(STATE_DOWNLOADED);
		lwm2m_engine_context_close(&firmware_ctx);
	}

	return 0;

error:
	set_update_result_from_error(ret);
	lwm2m_engine_context_close(&firmware_ctx);
	return ret;
}

static void do_transmit_timeout_cb(struct lwm2m_message *msg)
{
	int ret;

	if (firmware_retry < PACKET_TRANSFER_RETRY_MAX) {
		/* retry block */
		LOG_WRN("TIMEOUT - Sending a retry packet!");

		ret = transfer_request(&firmware_block_ctx,
				       msg->token, msg->tkl,
				       do_firmware_transfer_reply_cb);
		if (ret < 0) {
			/* abort retries / transfer */
			set_update_result_from_error(ret);
			firmware_retry = PACKET_TRANSFER_RETRY_MAX;
			lwm2m_engine_context_close(&firmware_ctx);
			return;
		}

		firmware_retry++;
	} else {
		LOG_ERR("TIMEOUT - Too many retry packet attempts! "
			"Aborting firmware download.");
		lwm2m_firmware_set_update_result(RESULT_CONNECTION_LOST);
		lwm2m_engine_context_close(&firmware_ctx);
	}
}

static void firmware_transfer(void)
{
	int ret;
	char *server_addr;

#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT)
	server_addr = CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_ADDR;
	if (strlen(server_addr) >= URI_LEN) {
		LOG_ERR("Invalid Proxy URI: %s", log_strdup(server_addr));
		ret = -ENOTSUP;
		goto error;
	}

	/* Copy required as it gets modified when port is available */
	strcpy(proxy_uri, server_addr);
	server_addr = proxy_uri;
#else
	server_addr = firmware_uri;
#endif

	ret = lwm2m_parse_peerinfo(server_addr, &firmware_ctx.remote_addr,
				   &firmware_ctx.use_dtls);
	if (ret < 0) {
		LOG_ERR("Failed to parse server URI.");
		goto error;
	}

	lwm2m_engine_context_init(&firmware_ctx);
	ret = lwm2m_socket_start(&firmware_ctx);
	if (ret < 0) {
		LOG_ERR("Cannot start a firmware-pull connection:%d", ret);
		goto error;
	}

	LOG_INF("Connecting to server %s", log_strdup(firmware_uri));

	/* reset block transfer context */
	coap_block_transfer_init(&firmware_block_ctx,
				 lwm2m_default_block_size(), 0);
	ret = transfer_request(&firmware_block_ctx, coap_next_token(), 8,
			       do_firmware_transfer_reply_cb);
	if (ret < 0) {
		goto error;
	}

	return;

error:
	set_update_result_from_error(ret);
	lwm2m_engine_context_close(&firmware_ctx);
}

static void socket_fault_cb(int error)
{
	int ret;

	LOG_ERR("FW update socket error: %d", error);

	lwm2m_engine_context_close(&firmware_ctx);

	/* Reopen the socket and retransmit the last request. */
	lwm2m_engine_context_init(&firmware_ctx);
	ret = lwm2m_socket_start(&firmware_ctx);
	if (ret < 0) {
		LOG_ERR("Failed to start a firmware-pull connection: %d", ret);
		goto error;
	}

	ret = transfer_request(&firmware_block_ctx,
			       NULL, LWM2M_MSG_TOKEN_GENERATE_NEW,
			       do_firmware_transfer_reply_cb);
	if (ret < 0) {
		LOG_ERR("Failed to send a retry packet: %d", ret);
		goto error;
	}

	return;

error:
	/* Abort retries. */
	firmware_retry = PACKET_TRANSFER_RETRY_MAX;
	set_update_result_from_error(ret);
	lwm2m_engine_context_close(&firmware_ctx);
}

/* TODO: */
int lwm2m_firmware_cancel_transfer(void)
{
	return 0;
}

int lwm2m_firmware_start_transfer(char *package_uri)
{
	/* close old socket */
	if (firmware_ctx.sock_fd > -1) {
		lwm2m_engine_context_close(&firmware_ctx);
	}

	(void)memset(&firmware_ctx, 0, sizeof(struct lwm2m_ctx));
	firmware_ctx.sock_fd = -1;
	firmware_ctx.fault_cb = socket_fault_cb;
	firmware_retry = 0;
	lwm2m_firmware_set_update_state(STATE_DOWNLOADING);

	/* start file transfer */
	strncpy(firmware_uri, package_uri, URI_LEN - 1);
	firmware_transfer();

	return 0;
}

/**
 * @brief Get the block context of the current firmware block.
 *
 * @return A pointer to the firmware block context
 */
struct coap_block_context *lwm2m_firmware_get_block_context()
{
	return &firmware_block_ctx;
}
