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

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

#include <mgmt/mcumgr/transport/smp_internal.h>

void smp_reassembly_init(struct smp_transport *smpt)
{
	smpt->__reassembly.current = NULL;
	smpt->__reassembly.expected = 0;
}

int smp_reassembly_expected(const struct smp_transport *smpt)
{
	if (smpt->__reassembly.current == NULL) {
		return -EINVAL;
	}

	return smpt->__reassembly.expected;
}

int smp_reassembly_collect(struct smp_transport *smpt, const void *buf, uint16_t len)
{
	if (smpt->__reassembly.current == NULL) {
		/*
		 * Collecting the first fragment: need to allocate buffer for it and prepare
		 * the reassembly context.
		 */
		if (len >= sizeof(struct smp_hdr)) {
			uint16_t expected = sys_be16_to_cpu(((struct smp_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 smp_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;
			}

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

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

	return smpt->__reassembly.expected;
}

int smp_reassembly_complete(struct smp_transport *smpt, bool force)
{
	if (smpt->__reassembly.current == NULL) {
		return -EINVAL;
	}

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

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

int smp_reassembly_drop(struct smp_transport *smpt)
{
	if (smpt->__reassembly.current == NULL) {
		return -EINVAL;
	}

	smp_packet_free(smpt->__reassembly.current);
	smpt->__reassembly.expected = 0;
	smpt->__reassembly.current = NULL;

	return 0;
}

void *smp_reassembly_get_ud(const struct smp_transport *smpt)
{
	if (smpt->__reassembly.current != NULL) {
		return net_buf_user_data(smpt->__reassembly.current);
	}

	return NULL;
}
