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

#include <zephyr.h>
#include <sys/byteorder.h>
#include <net/buf.h>
#include <mgmt/mcumgr/buf.h>
#include <mgmt/mcumgr/smp.h>
#include <mgmt/mgmt.h>
#include <smp/smp.h>

void zephyr_smp_reassembly_init(struct zephyr_smp_transport *zst)
{
	zst->__reassembly.current = NULL;
	zst->__reassembly.expected = 0;
}

int zephyr_smp_reassembly_expected(const struct zephyr_smp_transport *zst)
{
	if (zst->__reassembly.current == NULL) {
		return -EINVAL;
	}

	return zst->__reassembly.expected;
}

int zephyr_smp_reassembly_collect(struct zephyr_smp_transport *zst, const void *buf, uint16_t len)
{
	if (zst->__reassembly.current == NULL) {
		/*
		 * Collecting the first fragment: need to allocate buffer for it and prepare
		 * the reassembly context.
		 */
		if (len >= sizeof(struct mgmt_hdr)) {
			uint16_t expected = sys_be16_to_cpu(((struct mgmt_hdr *)buf)->nh_len);

			/*
			 * The length field in the header does not count the header size,
			 * but the reassembly does so the size needs to be added to the number of
			 * expected bytes.
			 */
			expected += sizeof(struct mgmt_hdr);

			/* Joining net_bufs not supported yet */
			if (len > CONFIG_MCUMGR_BUF_SIZE || expected > CONFIG_MCUMGR_BUF_SIZE) {
				return -ENOSR;
			}

			if (len > expected) {
				return -EOVERFLOW;
			}

			zst->__reassembly.current = mcumgr_buf_alloc();
			if (zst->__reassembly.current != NULL) {
				zst->__reassembly.expected = expected;
			} else {
				return -ENOMEM;
			}
		} else {
			/* Not enough data to even collect header */
			return -ENODATA;
		}
	}

	/* len is expected to be > 0 */
	if (zst->__reassembly.expected >= len) {
		net_buf_add_mem(zst->__reassembly.current, buf, len);
		zst->__reassembly.expected -= len;
	} else {
		/*
		 * A fragment is longer than the expected size and will not fit into the buffer.
		 */
		return -EOVERFLOW;
	}

	return zst->__reassembly.expected;
}

int zephyr_smp_reassembly_complete(struct zephyr_smp_transport *zst, bool force)
{
	if (zst->__reassembly.current == NULL) {
		return -EINVAL;
	}

	if (zst->__reassembly.expected == 0 || force) {
		int expected = zst->__reassembly.expected;

		zephyr_smp_rx_req(zst, zst->__reassembly.current);
		zst->__reassembly.expected = 0;
		zst->__reassembly.current = NULL;
		return expected;
	}
	return -ENODATA;
}

int zephyr_smp_reassembly_drop(struct zephyr_smp_transport *zst)
{
	if (zst->__reassembly.current == NULL) {
		return -EINVAL;
	}

	mcumgr_buf_free(zst->__reassembly.current);
	zst->__reassembly.expected = 0;
	zst->__reassembly.current = NULL;

	return 0;
}

void *zephyr_smp_reassembly_get_ud(const struct zephyr_smp_transport *zst)
{
	if (zst->__reassembly.current != NULL) {
		return net_buf_user_data(zst->__reassembly.current);
	}

	return NULL;
}
