/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL);

#include <zephyr/net/socket.h>

#include <zephyr/net/coap.h>
#include <zephyr/net/coap_client.h>

#define COAP_VERSION 1
#define COAP_PATH_ELEM_DELIM '/'
#define COAP_PATH_ELEM_QUERY '?'
#define COAP_PATH_ELEM_AMP '&'
#define COAP_SEPARATE_TIMEOUT 6000
#define DEFAULT_RETRY_AMOUNT 5
#define BLOCK1_OPTION_SIZE 4
#define PAYLOAD_MARKER_SIZE 1

static int coap_client_schedule_poll(struct coap_client *client, int sock,
				     struct coap_client_request *req)
{
	client->fd = sock;
	client->coap_request = req;

	k_sem_give(&client->coap_client_recv_sem);
	atomic_set(&client->coap_client_recv_active, 1);

	return 0;
}

static int send_request(int sock, const void *buf, size_t len, int flags,
			const struct sockaddr *dest_addr, socklen_t addrlen)
{
	if (addrlen == 0) {
		return sendto(sock, buf, len, flags, NULL, 0);
	} else {
		return sendto(sock, buf, len, flags, dest_addr, addrlen);
	}
}

static int receive(int sock, void *buf, size_t max_len, int flags,
		   struct sockaddr *src_addr, socklen_t *addrlen)
{
	if (*addrlen == 0) {
		return recvfrom(sock, buf, max_len, flags, NULL, NULL);
	} else {
		return recvfrom(sock, buf, max_len, flags, src_addr, addrlen);
	}
}

static void reset_block_contexts(struct coap_client *client)
{
	client->recv_blk_ctx.block_size = 0;
	client->recv_blk_ctx.total_size = 0;
	client->recv_blk_ctx.current = 0;

	client->send_blk_ctx.block_size = 0;
	client->send_blk_ctx.total_size = 0;
	client->send_blk_ctx.current = 0;
}

static int coap_client_init_path_options(struct coap_packet *pckt, const char *path)
{
	int ret = 0;
	int path_start, path_end;
	int path_length;
	bool contains_query = false;
	int i;

	path_start = 0;
	path_end = 0;
	path_length = strlen(path);
	for (i = 0; i < path_length; i++) {
		path_end = i;
		if (path[i] == COAP_PATH_ELEM_DELIM) {
			/* Guard for preceding delimiters */
			if (path_start < path_end) {
				ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH,
								path + path_start,
								path_end - path_start);
				if (ret < 0) {
					LOG_ERR("Failed to append path to CoAP message");
					goto out;
				}
			}
			/* Check if there is a new path after delimiter,
			 * if not, point to the end of string to not add
			 * new option after this
			 */
			if (path_length > i + 1) {
				path_start = i + 1;
			} else {
				path_start = path_length;
			}
		} else if (path[i] == COAP_PATH_ELEM_QUERY) {
			/* Guard for preceding delimiters */
			if (path_start < path_end) {
				ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH,
								path + path_start,
								path_end - path_start);
				if (ret < 0) {
					LOG_ERR("Failed to append path to CoAP message");
					goto out;
				}
			}
			/* Rest of the path is query */
			contains_query = true;
			if (path_length > i + 1) {
				path_start = i + 1;
			} else {
				path_start = path_length;
			}
			break;
		}
	}

	if (contains_query) {
		for (i = path_start; i < path_length; i++) {
			path_end = i;
			if (path[i] == COAP_PATH_ELEM_AMP || path[i] == COAP_PATH_ELEM_QUERY) {
				/* Guard for preceding delimiters */
				if (path_start < path_end) {
					ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY,
									path + path_start,
									path_end - path_start);
					if (ret < 0) {
						LOG_ERR("Failed to append path to CoAP message");
						goto out;
					}
				}
				/* Check if there is a new query option after delimiter,
				 * if not, point to the end of string to not add
				 * new option after this
				 */
				if (path_length > i + 1) {
					path_start = i + 1;
				} else {
					path_start = path_length;
				}
			}
		}
	}

	if (path_start < path_end) {
		if (contains_query) {
			ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY,
							path + path_start,
							path_end - path_start + 1);
		} else {
			ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH,
							path + path_start,
							path_end - path_start + 1);
		}
		if (ret < 0) {
			LOG_ERR("Failed to append path to CoAP message");
			goto out;
		}
	}

out:
	return ret;
}

static enum coap_block_size coap_client_default_block_size(void)
{
	switch (CONFIG_COAP_CLIENT_BLOCK_SIZE) {
	case 16:
		return COAP_BLOCK_16;
	case 32:
		return COAP_BLOCK_32;
	case 64:
		return COAP_BLOCK_64;
	case 128:
		return COAP_BLOCK_128;
	case 256:
		return COAP_BLOCK_256;
	case 512:
		return COAP_BLOCK_512;
	case 1024:
		return COAP_BLOCK_1024;
	}

	return COAP_BLOCK_256;
}

static int coap_client_init_request(struct coap_client *client,
				    struct coap_client_request *req)
{
	int ret = 0;
	int i;

	memset(client->send_buf, 0, sizeof(client->send_buf));
	ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, 1,
			       req->confirmable ? COAP_TYPE_CON : COAP_TYPE_NON_CON,
			       COAP_TOKEN_MAX_LEN, coap_next_token(), req->method,
			       coap_next_id());

	if (ret < 0) {
		LOG_ERR("Failed to init CoAP message %d", ret);
		goto out;
	}

	ret = coap_client_init_path_options(&client->request, req->path);

	if (ret < 0) {
		LOG_ERR("Failed to parse path to options %d", ret);
		goto out;
	}

	ret = coap_append_option_int(&client->request, COAP_OPTION_CONTENT_FORMAT, req->fmt);

	if (ret < 0) {
		LOG_ERR("Failed to append content format option");
		goto out;
	}

	/* Blockwise receive ongoing, request next block. */
	if (client->recv_blk_ctx.current > 0) {
		ret = coap_append_block2_option(&client->request, &client->recv_blk_ctx);

		if (ret < 0) {
			LOG_ERR("Failed to append block 2 option");
			goto out;
		}
	}

	/* Add extra options if any */
	for (i = 0; i < req->num_options; i++) {
		ret = coap_packet_append_option(&client->request, req->options[i].code,
						req->options[i].value, req->options[i].len);

		if (ret < 0) {
			LOG_ERR("Failed to append %d option", req->options[i].code);
			goto out;
		}
	}

	if (req->payload) {
		uint16_t payload_len;
		uint16_t offset;

		/* Blockwise send ongoing, add block1 */
		if (client->send_blk_ctx.total_size > 0 ||
		   (req->len > CONFIG_COAP_CLIENT_MESSAGE_SIZE)) {

			if (client->send_blk_ctx.total_size == 0) {
				coap_block_transfer_init(&client->send_blk_ctx,
							 coap_client_default_block_size(),
							 req->len);
			}
			ret = coap_append_block1_option(&client->request, &client->send_blk_ctx);

			if (ret < 0) {
				LOG_ERR("Failed to append block1 option");
				goto out;
			}
		}

		ret = coap_packet_append_payload_marker(&client->request);

		if (ret < 0) {
			LOG_ERR("Failed to append payload marker to CoAP message");
			goto out;
		}

		if (client->send_blk_ctx.total_size > 0) {
			uint16_t block_in_bytes =
				coap_block_size_to_bytes(client->send_blk_ctx.block_size);

			payload_len = client->send_blk_ctx.total_size -
				      client->send_blk_ctx.current;
			if (payload_len > block_in_bytes) {
				payload_len = block_in_bytes;
			}
			offset = client->send_blk_ctx.current;
		} else {
			payload_len = req->len;
			offset = 0;
		}

		ret = coap_packet_append_payload(&client->request, req->payload + offset,
						 payload_len);

		if (ret < 0) {
			LOG_ERR("Failed to append payload to CoAP message");
			goto out;
		}

		if (client->send_blk_ctx.total_size > 0) {
			coap_next_block(&client->request, &client->send_blk_ctx);
		}
	}
	client->request_tkl = coap_header_get_token(&client->request, client->request_token);
out:
	return ret;
}


int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr,
		    struct coap_client_request *req, int retries)
{
	int ret;

	if (client->coap_client_recv_active) {
		return -EAGAIN;
	}

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

	if (addr != NULL) {
		memcpy(&client->address, addr, sizeof(*addr));
		client->socklen = sizeof(client->address);
	} else {
		memset(&client->address, 0, sizeof(client->address));
		client->socklen = 0;
	}

	if (retries == -1) {
		client->retry_count = DEFAULT_RETRY_AMOUNT;
	} else {
		client->retry_count = retries;
	}

	ret = coap_client_init_request(client, req);
	if (ret < 0) {
		LOG_ERR("Failed to initialize coap request");
		return ret;
	}

	ret = coap_client_schedule_poll(client, sock, req);
	if (ret < 0) {
		LOG_ERR("Failed to schedule polling");
		goto out;
	}

	ret = coap_pending_init(&client->pending, &client->request, &client->address,
				client->retry_count);

	if (ret < 0) {
		LOG_ERR("Failed to initialize pending struct");
		goto out;
	}

	coap_pending_cycle(&client->pending);

	ret = send_request(sock, client->request.data, client->request.offset, 0, &client->address,
			   client->socklen);

	if (ret < 0) {
		LOG_ERR("Transmission failed: %d", errno);
	} else {
		/* Do not return the number of bytes sent */
		ret = 0;
	}
out:
	return ret;
}

static int handle_poll(struct coap_client *client)
{
	int ret = 0;

	while (1) {
		struct pollfd fds;

		fds.fd = client->fd;
		fds.events = POLLIN;
		fds.revents = 0;
		/* rfc7252#section-5.2.2, use separate timeout value for a separate response */
		if (client->pending.timeout != 0) {
			ret = poll(&fds, 1, client->pending.timeout);
		} else {
			ret = poll(&fds, 1, COAP_SEPARATE_TIMEOUT);
		}

		if (ret < 0) {
			LOG_ERR("Error in poll:%d", errno);
			errno = 0;
			return ret;
		} else if (ret == 0) {
			if (client->pending.timeout != 0 && coap_pending_cycle(&client->pending)) {
				LOG_ERR("Timeout in poll, retrying send");
				send_request(client->fd, client->request.data,
					     client->request.offset, 0, &client->address,
					     client->socklen);
			} else {
				/* No more retries left, don't retry */
				LOG_ERR("Timeout in poll, no more retries");
				ret = -EFAULT;
				break;
			}
		} else {
			if (fds.revents & POLLERR) {
				LOG_ERR("Error in poll");
				ret = -EIO;
				break;
			}

			if (fds.revents & POLLHUP) {
				LOG_ERR("Error in poll: POLLHUP");
				ret = -ECONNRESET;
				break;
			}

			if (fds.revents & POLLNVAL) {
				LOG_ERR("Error in poll: POLLNVAL - fd not open");
				ret = -EINVAL;
				break;
			}

			if (!(fds.revents & POLLIN)) {
				LOG_ERR("Unknown poll error");
				ret = -EINVAL;
				break;
			}

			ret = 0;
			break;
		}
	}

	return ret;
}

static bool token_compare(struct coap_client *client, const struct coap_packet *resp)
{
	uint8_t response_token[COAP_TOKEN_MAX_LEN];
	uint8_t response_tkl;

	response_tkl = coap_header_get_token(resp, response_token);

	if (client->request_tkl != response_tkl) {
		return false;
	}

	return memcmp(&client->request_token, &response_token, response_tkl) == 0;
}

static int recv_response(struct coap_client *client, struct coap_packet *response)
{
	int len;
	int ret;

	memset(client->recv_buf, 0, sizeof(client->recv_buf));
	len = receive(client->fd, client->recv_buf, sizeof(client->recv_buf), MSG_DONTWAIT,
		      &client->address, &client->socklen);

	if (len < 0) {
		LOG_ERR("Error reading response: %d", errno);
		return -EINVAL;
	} else if (len == 0) {
		LOG_ERR("Zero length recv");
		return -EINVAL;
	}

	LOG_DBG("Received %d bytes", len);

	ret = coap_packet_parse(response, client->recv_buf, len, NULL, 0);
	if (ret < 0) {
		LOG_ERR("Invalid data received");
		return ret;
	}

	return ret;
}

static void report_callback_error(struct coap_client *client, int error_code)
{
	if (client->coap_request->cb) {
		client->coap_request->cb(error_code, 0, NULL, 0, true,
					 client->coap_request->user_data);
	}
}

static int send_ack(struct coap_client *client, const struct coap_packet *req,
		    uint8_t response_code)
{
	int ret;

	ret = coap_ack_init(&client->request, req, client->send_buf, MAX_COAP_MSG_LEN,
			    response_code);
	if (ret < 0) {
		LOG_ERR("Failed to initialize CoAP ACK-message");
		return ret;
	}

	ret = send_request(client->fd, client->request.data, client->request.offset, 0,
			   &client->address, client->socklen);
	if (ret < 0) {
		LOG_ERR("Error sending a CoAP ACK-message");
		return ret;
	}

	return 0;
}

static int send_reset(struct coap_client *client, const struct coap_packet *req,
		      uint8_t response_code)
{
	int ret;
	uint16_t id;
	uint8_t token[COAP_TOKEN_MAX_LEN];
	uint8_t tkl;

	id = coap_header_get_id(req);
	tkl = response_code ? coap_header_get_token(req, token) : 0;
	ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, COAP_VERSION,
			       COAP_TYPE_RESET, tkl, token, response_code, id);

	if (ret < 0) {
		LOG_ERR("Error creating CoAP reset message");
		return ret;
	}

	ret = send_request(client->fd, client->request.data, client->request.offset, 0,
			   &client->address, client->socklen);
	if (ret < 0) {
		LOG_ERR("Error sending CoAP reset message");
		return ret;
	}

	return 0;
}

static int handle_response(struct coap_client *client, const struct coap_packet *response)
{
	int ret = 0;
	int response_type;
	int block_option;
	int block_num;
	bool blockwise_transfer = false;
	bool last_block = false;

	/* Handle different types, ACK might be separate or piggybacked
	 * CON and NCON contains a separate response, CON needs an empty response
	 * CON request results as ACK and possibly separate CON or NCON response
	 * NCON request results only as a separate CON or NCON message as there is no ACK
	 * With RESET, just drop gloves and call the callback.
	 */
	response_type = coap_header_get_type(response);

	/* Reset and Ack need to match the message ID with request */
	if ((response_type == COAP_TYPE_ACK || response_type == COAP_TYPE_RESET) &&
	     coap_header_get_id(response) != client->pending.id)  {
		LOG_ERR("Unexpected ACK or Reset");
		return -EFAULT;
	} else if (response_type == COAP_TYPE_RESET) {
		coap_pending_clear(&client->pending);
	}

	/* CON, NON_CON and piggybacked ACK need to match the token with original request */
	uint16_t payload_len;
	uint8_t response_code = coap_header_get_code(response);
	const uint8_t *payload = coap_packet_get_payload(response, &payload_len);

	/* Separate response */
	if (payload_len == 0 && response_type == COAP_TYPE_ACK &&
	    response_code == COAP_CODE_EMPTY) {
		/* Clear the pending, poll uses now the separate timeout for the response. */
		coap_pending_clear(&client->pending);
		return 1;
	}

	/* Check for tokens */
	if (!token_compare(client, response)) {
		LOG_ERR("Not matching tokens, respond with reset");
		ret = send_reset(client, response, COAP_RESPONSE_CODE_NOT_FOUND);
		return 1;
	}

	/* Send ack for CON */
	if (response_type == COAP_TYPE_CON) {
		/* CON response is always a separate response, respond with empty ACK. */
		ret = send_ack(client, response, COAP_CODE_EMPTY);
		if (ret < 0) {
			goto fail;
		}
	}

	if (client->pending.timeout != 0) {
		coap_pending_clear(&client->pending);
	}

	/* Check if block2 exists */
	block_option = coap_get_option_int(response, COAP_OPTION_BLOCK2);
	if (block_option > 0) {
		blockwise_transfer = true;
		last_block = !GET_MORE(block_option);
		block_num = GET_BLOCK_NUM(block_option);

		if (block_num == 0) {
			coap_block_transfer_init(&client->recv_blk_ctx,
						 coap_client_default_block_size(),
						 0);
			client->offset = 0;
		}

		ret = coap_update_from_block(response, &client->recv_blk_ctx);
		if (ret < 0) {
			LOG_ERR("Error updating block context");
		}
		coap_next_block(response, &client->recv_blk_ctx);
	} else {
		client->offset = 0;
		last_block = true;
	}

	/* Check if this was a response to last blockwise send */
	if (client->send_blk_ctx.total_size > 0) {
		blockwise_transfer = true;
		if (client->send_blk_ctx.total_size == client->send_blk_ctx.current) {
			last_block = true;
		} else {
			last_block = false;
		}
	}

	/* Call user callback */
	if (client->coap_request->cb) {
		client->coap_request->cb(response_code, client->offset, payload, payload_len,
					 last_block, client->coap_request->user_data);

		/* Update the offset for next callback in a blockwise transfer */
		if (blockwise_transfer) {
			client->offset += payload_len;
		}
	}

	/* If this wasn't last block, send the next request */
	if (blockwise_transfer && !last_block) {
		ret = coap_client_init_request(client, client->coap_request);

		if (ret < 0) {
			LOG_ERR("Error creating a CoAP request");
			goto fail;
		}

		if (client->pending.timeout != 0) {
			LOG_ERR("Previous pending hasn't arrived");
			goto fail;
		}

		ret = coap_pending_init(&client->pending, &client->request, &client->address,
					client->retry_count);
		if (ret < 0) {
			LOG_ERR("Error creating pending");
			goto fail;
		}
		coap_pending_cycle(&client->pending);

		ret = send_request(client->fd, client->request.data, client->request.offset, 0,
				   &client->address, client->socklen);
		if (ret < 0) {
			LOG_ERR("Error sending a CoAP request");
			goto fail;
		} else {
			return 1;
		}
	}
fail:
	return ret;
}

void coap_client_recv(void *coap_cl, void *a, void *b)
{
	int ret;
	struct coap_client *const client = coap_cl;

	reset_block_contexts(client);
	k_sem_take(&client->coap_client_recv_sem, K_FOREVER);
	while (true) {
		struct coap_packet response;

		atomic_set(&client->coap_client_recv_active, 1);
		ret = handle_poll(client);
		if (ret < 0) {
			/* Error in polling, clear pending. */
			LOG_ERR("Error in poll");
			coap_pending_clear(&client->pending);
			report_callback_error(client, ret);
			goto idle;
		}

		ret = recv_response(client, &response);
		if (ret < 0) {
			LOG_ERR("Error receiving response");
			report_callback_error(client, ret);
			goto idle;
		}

		ret = handle_response(client, &response);
		if (ret < 0) {
			LOG_ERR("Error handling respnse");
			report_callback_error(client, ret);
			goto idle;
		}

		/* There are more messages coming for the original request */
		if (ret > 0) {
			continue;
		} else {
idle:
			reset_block_contexts(client);
			atomic_set(&client->coap_client_recv_active, 0);
			k_sem_take(&client->coap_client_recv_sem, K_FOREVER);
		}
	}
}

int coap_client_init(struct coap_client *client, const char *info)
{
	if (client == NULL) {
		return -EINVAL;
	}

	client->fd = -1;
	k_sem_init(&client->coap_client_recv_sem, 0, 1);

	client->tid =
		k_thread_create(&client->thread, client->coap_thread_stack,
				K_THREAD_STACK_SIZEOF(client->coap_thread_stack),
				coap_client_recv, client, NULL, NULL,
				CONFIG_COAP_CLIENT_THREAD_PRIORITY, 0, K_NO_WAIT);

	if (IS_ENABLED(CONFIG_THREAD_NAME)) {
		if (info != NULL) {
			k_thread_name_set(client->tid, info);
		} else {
			k_thread_name_set(client->tid, "coap_client");
		}
	}

	return 0;
}
