/*
 * Copyright Runtime.io 2018. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include "net/buf.h"
#include "mgmt/mgmt.h"
#include "mgmt/buf.h"
#include "smp/smp.h"
#include "mgmt/smp.h"

static mgmt_alloc_rsp_fn zephyr_smp_alloc_rsp;
static mgmt_trim_front_fn zephyr_smp_trim_front;
static mgmt_reset_buf_fn zephyr_smp_reset_buf;
static mgmt_write_at_fn zephyr_smp_write_at;
static mgmt_init_reader_fn zephyr_smp_init_reader;
static mgmt_init_writer_fn zephyr_smp_init_writer;
static mgmt_free_buf_fn zephyr_smp_free_buf;
static smp_tx_rsp_fn zephyr_smp_tx_rsp;

static const struct mgmt_streamer_cfg zephyr_smp_cbor_cfg = {
	.alloc_rsp = zephyr_smp_alloc_rsp,
	.trim_front = zephyr_smp_trim_front,
	.reset_buf = zephyr_smp_reset_buf,
	.write_at = zephyr_smp_write_at,
	.init_reader = zephyr_smp_init_reader,
	.init_writer = zephyr_smp_init_writer,
	.free_buf = zephyr_smp_free_buf,
};

void *
zephyr_smp_alloc_rsp(const void *req, void *arg)
{
	const struct net_buf_pool *pool;
	const struct net_buf *req_nb;
	struct net_buf *rsp_nb;

	req_nb = req;

	rsp_nb = mcumgr_buf_alloc();
	if (rsp_nb == NULL) {
		return NULL;
	}

	pool = net_buf_pool_get(req_nb->pool_id);
	memcpy(net_buf_user_data(rsp_nb),
	       net_buf_user_data((void *)req_nb),
	       sizeof(req_nb->user_data));

	return rsp_nb;
}

static void
zephyr_smp_trim_front(void *buf, size_t len, void *arg)
{
	struct net_buf *nb;

	nb = buf;
	if (len > nb->len) {
		len = nb->len;
	}

	net_buf_pull(nb, len);
}

/**
 * Splits an appropriately-sized fragment from the front of a net_buf, as
 * neeeded.  If the length of the net_buf is greater than specified maximum
 * fragment size, a new net_buf is allocated, and data is moved from the source
 * net_buf to the new net_buf.  If the net_buf is small enough to fit in a
 * single fragment, the source net_buf is returned unmodified, and the supplied
 * pointer is set to NULL.
 *
 * This function is expected to be called in a loop until the entire source
 * net_buf has been consumed.  For example:
 *
 *     struct net_buf *frag;
 *     struct net_buf *rsp;
 *     // [...]
 *     while (rsp != NULL) {
 *         frag = zephyr_smp_split_frag(&rsp, get_mtu());
 *         if (frag == NULL) {
 *             net_buf_unref(nb);
 *             return SYS_ENOMEM;
 *         }
 *         send_packet(frag)
 *     }
 *
 * @param nb                    The packet to fragment.  Upon fragmentation,
 *                                  this net_buf is adjusted such that the
 *                                  fragment data is removed.  If the packet
 *                                  constitutes a single fragment, this gets
 *                                  set to NULL on success.
 * @param mtu                   The maximum payload size of a fragment.
 *
 * @return                      The next fragment to send on success;
 *                              NULL on failure.
 */
static struct net_buf *
zephyr_smp_split_frag(struct net_buf **nb, u16_t mtu)
{
	struct net_buf *frag;
	struct net_buf *src;

	src = *nb;

	if (src->len <= mtu) {
		*nb = NULL;
		frag = src;
	} else {
		frag = zephyr_smp_alloc_rsp(src, NULL);

		/* Copy fragment payload into new buffer. */
		net_buf_add_mem(frag, src->data, mtu);

		/* Remove fragment from total response. */
		zephyr_smp_trim_front(src, mtu, NULL);
	}

	return frag;
}

static void
zephyr_smp_reset_buf(void *buf, void *arg)
{
	net_buf_reset(buf);
}

static int
zephyr_smp_write_at(struct cbor_encoder_writer *writer, size_t offset,
		    const void *data, size_t len, void *arg)
{
	struct cbor_nb_writer *czw;
	struct net_buf *nb;

	czw = (struct cbor_nb_writer *)writer;
	nb = czw->nb;

	if (offset < 0 || offset > nb->len) {
		return MGMT_ERR_EINVAL;
	}

	if (len > net_buf_tailroom(nb)) {
		return MGMT_ERR_EINVAL;
	}

	memcpy(nb->data + offset, data, len);
	if (nb->len < offset + len) {
		nb->len = offset + len;
		writer->bytes_written = nb->len;
	}

	return 0;
}

static int
zephyr_smp_tx_rsp(struct smp_streamer *ns, void *rsp, void *arg)
{
	struct zephyr_smp_transport *zst;
	struct net_buf *frag;
	struct net_buf *nb;
	u16_t mtu;
	int rc;
	int i;

	zst = arg;
	nb = rsp;

	mtu = zst->zst_get_mtu(rsp);
	if (mtu == 0) {
		/* The transport cannot support a transmission right now. */
		return MGMT_ERR_EUNKNOWN;
	}

	i = 0;
	while (nb != NULL) {
		frag = zephyr_smp_split_frag(&nb, mtu);
		if (frag == NULL) {
			return MGMT_ERR_ENOMEM;
		}

		rc = zst->zst_output(zst, frag);
		if (rc != 0) {
			return MGMT_ERR_EUNKNOWN;
		}
	}

	return 0;
}

static void
zephyr_smp_free_buf(void *buf, void *arg)
{
	mcumgr_buf_free(buf);
}

static int
zephyr_smp_init_reader(struct cbor_decoder_reader *reader, void *buf,
		       void *arg)
{
	struct cbor_nb_reader *czr;

	czr = (struct cbor_nb_reader *)reader;
	cbor_nb_reader_init(czr, buf);

	return 0;
}

static int
zephyr_smp_init_writer(struct cbor_encoder_writer *writer, void *buf,
		       void *arg)
{
	struct cbor_nb_writer *czw;

	czw = (struct cbor_nb_writer *)writer;
	cbor_nb_writer_init(czw, buf);

	return 0;
}

/**
 * Processes a single SMP packet and sends the corresponding response(s).
 */
static int
zephyr_smp_process_packet(struct zephyr_smp_transport *zst,
			  struct net_buf *nb)
{
	struct cbor_nb_reader reader;
	struct cbor_nb_writer writer;
	struct smp_streamer streamer;
	int rc;

	streamer = (struct smp_streamer) {
		.mgmt_stmr = {
			.cfg = &zephyr_smp_cbor_cfg,
			.reader = &reader.r,
			.writer = &writer.enc,
			.cb_arg = zst,
		},
		.tx_rsp_cb = zephyr_smp_tx_rsp,
	};

	rc = smp_process_request_packet(&streamer, nb);
	return rc;
}

/**
 * Processes all received SNP request packets.
 */
static void
zephyr_smp_handle_reqs(struct k_work *work)
{
	struct zephyr_smp_transport *zst;
	struct net_buf *nb;

	zst = (void *)work;

	while ((nb = k_fifo_get(&zst->zst_fifo, K_NO_WAIT)) != NULL) {
		zephyr_smp_process_packet(zst, nb);
	}
}

void
zephyr_smp_transport_init(struct zephyr_smp_transport *zst,
			  zephyr_smp_transport_out_fn *output_func,
			  zephyr_smp_transport_get_mtu_fn *get_mtu_func)
{
	*zst = (struct zephyr_smp_transport) {
		.zst_output = output_func,
		.zst_get_mtu = get_mtu_func,
	};

	k_work_init(&zst->zst_work, zephyr_smp_handle_reqs);
	k_fifo_init(&zst->zst_fifo);
}

void
zephyr_smp_rx_req(struct zephyr_smp_transport *zst, struct net_buf *nb)
{
	k_fifo_put(&zst->zst_fifo, nb);
	k_work_submit(&zst->zst_work);
}
