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

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

#include <stdlib.h>
#include <stddef.h>
#include <zephyr/types.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>

#include <zephyr/sys/byteorder.h>

#include <zephyr/sys/printk.h>

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

static inline bool append_u8(struct coap_packet *cpkt, uint8_t data)
{
	if (!cpkt) {
		return false;
	}

	if (cpkt->max_len - cpkt->offset < 1) {
		return false;
	}

	cpkt->data[cpkt->offset++] = data;

	return true;
}

static inline bool append_be16(struct coap_packet *cpkt, uint16_t data)
{
	if (!cpkt) {
		return false;
	}

	if (cpkt->max_len - cpkt->offset < 2) {
		return false;
	}

	cpkt->data[cpkt->offset++] = data >> 8;
	cpkt->data[cpkt->offset++] = (uint8_t) data;

	return true;
}

static inline bool append(struct coap_packet *cpkt, const uint8_t *data, uint16_t len)
{
	if (!cpkt || !data) {
		return false;
	}

	if (cpkt->max_len - cpkt->offset < len) {
		return false;
	}

	memcpy(cpkt->data + cpkt->offset, data, len);
	cpkt->offset += len;

	return true;
}

static bool match_path_uri(const char * const *path,
			   const char *uri, uint16_t len)
{
	const char * const *p = NULL;
	int i, j, k, plen;

	if (!path) {
		return false;
	}

	if (len <= 1U || uri[0] != '/') {
		return false;
	}

	p = path;
	plen = *p ? strlen(*p) : 0;

	if (plen == 0) {
		return false;
	}

	/* Go through uri and try to find a matching path */
	for (i = 1; i < len; i++) {
		while (*p) {
			plen = strlen(*p);

			k = i;

			for (j = 0; j < plen; j++) {
				if (uri[k] == '*') {
					if ((k + 1) == len) {
						return true;
					}
				}

				if (uri[k] != (*p)[j]) {
					goto next;
				}

				k++;
			}

			if (i == (k - 1) && j == plen) {
				return true;
			}

			if (k == len && j == plen) {
				return true;
			}

next:
			p++;
		}
	}

	/* Did we find the resource or not */
	if (i == len && !*p) {
		return false;
	}

	return true;
}

static bool match_attributes(const char * const *attributes,
			     const struct coap_option *query)
{
	const char * const *attr;

	/* FIXME: deal with the case when there are multiple options in a
	 * query, for example: 'rt=lux temperature', if I want to list
	 * resources with resource type lux or temperature.
	 */
	for (attr = attributes; attr && *attr; attr++) {
		uint16_t attr_len = strlen(*attr);

		if (query->len != attr_len) {
			continue;
		}

		if (!strncmp((char *) query->value, *attr, attr_len)) {
			return true;
		}
	}

	return false;
}

static bool match_queries_resource(const struct coap_resource *resource,
				   const struct coap_option *query,
				   int num_queries)
{
	struct coap_core_metadata *meta = resource->user_data;
	const char * const *attributes = NULL;
	const int href_len = strlen("href");

	if (num_queries == 0) {
		return true;
	}

	if (meta && meta->attributes) {
		attributes = meta->attributes;
	}

	if (!attributes) {
		return false;
	}

	if (query->len > href_len + 1 &&
	    !strncmp((char *) query->value, "href", href_len)) {
		/* The stuff after 'href=' */
		const char *uri = (char *) query->value + href_len + 1;
		uint16_t uri_len  = query->len - (href_len + 1);

		return match_path_uri(resource->path, uri, uri_len);
	}

	return match_attributes(attributes, query);
}

#if defined(CONFIG_COAP_WELL_KNOWN_BLOCK_WISE)

#define MAX_BLOCK_WISE_TRANSFER_SIZE 2048

enum coap_block_size default_block_size(void)
{
	switch (CONFIG_COAP_WELL_KNOWN_BLOCK_WISE_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_64;
}

static bool append_to_coap_pkt(struct coap_packet *response,
			       const char *str, uint16_t len,
			       uint16_t *remaining, size_t *offset,
			       size_t current)
{
	uint16_t pos = 0U;
	bool res;

	if (!*remaining) {
		return true;
	}

	if (*offset < current) {
		pos = current - *offset;

		if (len >= pos) {
			len -= pos;
			*offset += pos;
		} else {
			*offset += len;
			return true;
		}
	}

	if (len > *remaining) {
		len = *remaining;
	}

	res = append(response, str + pos, len);

	*remaining -= len;
	*offset += len;

	return res;
}

static int format_uri(const char * const *path,
		      struct coap_packet *response,
		      uint16_t *remaining, size_t *offset,
		      size_t current, bool *more)
{
	static const char prefix[] = "</";
	const char * const *p;
	bool res;

	if (!path) {
		return -EINVAL;
	}

	res = append_to_coap_pkt(response, &prefix[0], sizeof(prefix) - 1,
				 remaining, offset, current);
	if (!res) {
		return -ENOMEM;
	}

	if (!*remaining) {
		*more = true;
		return 0;
	}

	for (p = path; *p; ) {
		uint16_t path_len = strlen(*p);

		res = append_to_coap_pkt(response, *p, path_len, remaining,
					 offset, current);
		if (!res) {
			return -ENOMEM;
		}

		if (!*remaining) {
			*more = true;
			return 0;
		}

		p++;
		if (!*p) {
			continue;
		}

		res = append_to_coap_pkt(response, "/", 1, remaining, offset,
					 current);
		if (!res) {
			return -ENOMEM;
		}

		if (!*remaining) {
			*more = true;
			return 0;
		}

	}

	res = append_to_coap_pkt(response, ">", 1, remaining, offset, current);
	if (!res) {
		return -ENOMEM;
	}

	if (!*remaining) {
		*more = true;
		return 0;
	}

	*more = false;

	return 0;
}

static int format_attributes(const char * const *attributes,
			     struct coap_packet *response,
			     uint16_t *remaining, size_t *offset,
			     size_t current, bool *more)
{
	const char * const *attr;
	bool res;

	if (!attributes) {
		*more = false;
		return 0;
	}

	for (attr = attributes; *attr; attr++) {
		int attr_len;

		res = append_to_coap_pkt(response, ";", 1,
					 remaining, offset, current);
		if (!res) {
			return -ENOMEM;
		}

		if (!*remaining) {
			*more = true;
			return 0;
		}

		attr_len = strlen(*attr);

		res = append_to_coap_pkt(response, *attr, attr_len,
					 remaining, offset, current);
		if (!res) {
			return -ENOMEM;
		}

		if (*(attr + 1) && !*remaining) {
			*more = true;
			return 0;
		}
	}

	*more = false;
	return 0;
}

static int format_resource(const struct coap_resource *resource,
			   struct coap_packet *response,
			   uint16_t *remaining, size_t *offset,
			   size_t current, bool *more)
{
	struct coap_core_metadata *meta = resource->user_data;
	const char * const *attributes = NULL;
	int r;

	r = format_uri(resource->path, response, remaining,
		       offset, current, more);
	if (r < 0) {
		return r;
	}

	if (!*remaining) {
		*more = true;
		return 0;
	}

	if (meta && meta->attributes) {
		attributes = meta->attributes;
	}

	return format_attributes(attributes, response, remaining, offset,
				 current, more);
}

/* coap_well_known_core_get() added Option (delta and len) with
 * out any extended options so this function will not consider Extended
 * options at the moment.
 */
int clear_more_flag(struct coap_packet *cpkt)
{
	uint16_t offset;
	uint8_t opt;
	uint8_t delta;
	uint8_t len;

	offset = cpkt->hdr_len;
	delta = 0U;

	while (1) {
		opt = cpkt->data[offset++];

		delta += ((opt & 0xF0) >> 4);
		len = (opt & 0xF);

		if (delta == COAP_OPTION_BLOCK2) {
			break;
		}

		offset += len;
	}

	/* As per RFC 7959 Sec 2.2 : NUM filed can be on 0-3 bytes.
	 * Skip NUM field to update M bit.
	 */
	if (len > 1) {
		offset = offset + len - 1;
	}

	cpkt->data[offset] = cpkt->data[offset] & 0xF7;

	return 0;
}

int coap_well_known_core_get(struct coap_resource *resource,
			      struct coap_packet *request,
			      struct coap_packet *response,
			      uint8_t *data, uint16_t len)
{
	static struct coap_block_context ctx;
	struct coap_option query;
	unsigned int num_queries;
	size_t offset;
	uint8_t token[COAP_TOKEN_MAX_LEN];
	uint16_t remaining;
	uint16_t id;
	uint8_t tkl;
	int r;
	bool more = false;

	if (!resource || !request || !response || !data || !len) {
		return -EINVAL;
	}

	if (ctx.total_size == 0) {
		/* We have to iterate through resources and it's attributes,
		 * total size is unknown, so initialize it to
		 * MAX_BLOCK_WISE_TRANSFER_SIZE and update it according to
		 * offset.
		 */
		coap_block_transfer_init(&ctx, default_block_size(),
					 MAX_BLOCK_WISE_TRANSFER_SIZE);
	}

	r = coap_update_from_block(request, &ctx);
	if (r < 0) {
		goto end;
	}

	id = coap_header_get_id(request);
	tkl = coap_header_get_token(request, token);

	/* Per RFC 6690, Section 4.1, only one (or none) query parameter may be
	 * provided, use the first if multiple.
	 */
	r = coap_find_options(request, COAP_OPTION_URI_QUERY, &query, 1);
	if (r < 0) {
		goto end;
	}

	num_queries = r;

	r = coap_packet_init(response, data, len, COAP_VERSION_1, COAP_TYPE_ACK,
			     tkl, token, COAP_RESPONSE_CODE_CONTENT, id);
	if (r < 0) {
		goto end;
	}

	r = coap_append_option_int(response, COAP_OPTION_CONTENT_FORMAT,
				   COAP_CONTENT_FORMAT_APP_LINK_FORMAT);
	if (r < 0) {
		goto end;
	}

	r = coap_append_block2_option(response, &ctx);
	if (r < 0) {
		goto end;
	}

	r = coap_packet_append_payload_marker(response);
	if (r < 0) {
		goto end;
	}

	offset = 0;
	remaining = coap_block_size_to_bytes(ctx.block_size);

	while (resource++ && resource->path) {
		if (!remaining) {
			more = true;
			break;
		}

		if (!match_queries_resource(resource, &query, num_queries)) {
			continue;
		}

		r = format_resource(resource, response, &remaining, &offset,
				    ctx.current, &more);
		if (r < 0) {
			goto end;
		}

		if ((resource + 1) && (resource + 1)->path) {
			r = append_to_coap_pkt(response, ",", 1, &remaining,
					       &offset, ctx.current);
			if (!r) {
				goto end;
			}
		}
	}

	/* Offset is the total size now, but block2 option is already
	 * appended. So update only 'more' flag.
	 */
	if (!more) {
		ctx.total_size = offset;
		r = clear_more_flag(response);
	}

end:
	/* So it's a last block, reset context */
	if (!more) {
		(void)memset(&ctx, 0, sizeof(ctx));
	}

	return r;
}

#else

static int format_uri(const char * const *path, struct coap_packet *response)
{
	const char * const *p;
	char *prefix = "</";
	bool res;

	if (!path) {
		return -EINVAL;
	}

	res = append(response, (uint8_t *) prefix, strlen(prefix));
	if (!res) {
		return -ENOMEM;
	}

	for (p = path; *p; ) {
		res = append(response, (uint8_t *) *p, strlen(*p));
		if (!res) {
			return -ENOMEM;
		}

		p++;
		if (*p) {
			res = append_u8(response, (uint8_t) '/');
			if (!res) {
				return -ENOMEM;
			}
		}
	}

	res = append_u8(response, (uint8_t) '>');
	if (!res) {
		return -ENOMEM;
	}

	return 0;
}

static int format_attributes(const char * const *attributes,
			     struct coap_packet *response)
{
	const char * const *attr;
	bool res;

	if (!attributes) {
		return 0;
	}

	for (attr = attributes; *attr; attr++) {
		res = append_u8(response, (uint8_t) ';');
		if (!res) {
			return -ENOMEM;
		}

		res = append(response, (uint8_t *) *attr, strlen(*attr));
		if (!res) {
			return -ENOMEM;
		}
	}

	return 0;
}

static int format_resource(const struct coap_resource *resource,
			   struct coap_packet *response)
{
	struct coap_core_metadata *meta = resource->user_data;
	const char * const *attributes = NULL;
	int r;

	r = format_uri(resource->path, response);
	if (r < 0) {
		return r;
	}

	if (meta && meta->attributes) {
		attributes = meta->attributes;
	}

	return format_attributes(attributes, response);
}

int coap_well_known_core_get(struct coap_resource *resource,
			     struct coap_packet *request,
			     struct coap_packet *response,
			     uint8_t *data, uint16_t len)
{
	struct coap_option query;
	uint8_t token[COAP_TOKEN_MAX_LEN];
	uint16_t id;
	uint8_t tkl;
	uint8_t num_queries;
	int r;

	if (!resource || !request || !response || !data || !len) {
		return -EINVAL;
	}

	id = coap_header_get_id(request);
	tkl = coap_header_get_token(request, token);

	/* Per RFC 6690, Section 4.1, only one (or none) query parameter may be
	 * provided, use the first if multiple.
	 */
	r = coap_find_options(request, COAP_OPTION_URI_QUERY, &query, 1);
	if (r < 0) {
		return r;
	}

	num_queries = r;

	r = coap_packet_init(response, data, len, COAP_VERSION_1, COAP_TYPE_ACK,
			     tkl, token, COAP_RESPONSE_CODE_CONTENT, id);
	if (r < 0) {
		return r;
	}

	r = coap_append_option_int(response, COAP_OPTION_CONTENT_FORMAT,
				   COAP_CONTENT_FORMAT_APP_LINK_FORMAT);
	if (r < 0) {
		return -EINVAL;
	}

	r = coap_packet_append_payload_marker(response);
	if (r < 0) {
		return -EINVAL;
	}

	while (resource++ && resource->path) {
		if (!match_queries_resource(resource, &query, num_queries)) {
			continue;
		}

		r = format_resource(resource, response);
		if (r < 0) {
			return r;
		}

		if ((resource + 1)->path) {
			r = append_u8(response, (uint8_t) ',');
			if (!r) {
				return -ENOMEM;
			}
		}
	}

	return 0;
}
#endif

/* Exposing some of the APIs to CoAP unit tests in tests/net/lib/coap */
#if defined(CONFIG_COAP_TEST_API_ENABLE)
bool _coap_match_path_uri(const char * const *path,
			  const char *uri, uint16_t len)
{
	return match_path_uri(path, uri, len);
}
#endif
