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

#include <zephyr/net/buf.h>
#include <zephyr/kernel.h>
#include <string.h>
#include <zephyr/mgmt/mcumgr/smp/smp_client.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/sys/byteorder.h>
#include <mgmt/mcumgr/transport/smp_internal.h>
#include "smp_stub.h"

K_THREAD_STACK_DEFINE(smp_stub_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE);

static mcmgr_client_data_check_fn rx_verify_cb;
static int send_client_failure;
static struct net_buf *response_buf;
static struct smp_hdr res_hdr;
static struct smp_transport smpt_test;
static struct smp_client_transport_entry smp_client_transport;
static struct k_work_q smp_work_queue;
static struct k_work stub_work;

static const struct k_work_queue_config smp_work_queue_config = {
	.name = "mcumgr smp"
};

void smp_stub_set_rx_data_verify(mcmgr_client_data_check_fn cb)
{
	rx_verify_cb = cb;
}

void smp_client_send_status_stub(int status)
{
	send_client_failure = status;
}

struct net_buf *smp_response_buf_allocation(void)
{
	smp_client_response_buf_clean();

	response_buf = smp_packet_alloc();

	return response_buf;
}

void smp_client_response_buf_clean(void)
{
	if (response_buf) {
		smp_client_buf_free(response_buf);
		response_buf = NULL;
	}
}

void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr)
{
	memcpy(dst_hdr, nb->data, sizeof(*dst_hdr));
	dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len);
	dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group);
}


static uint16_t smp_uart_get_mtu(const struct net_buf *nb)
{
	return 256;
}

static int smp_uart_tx_pkt(struct net_buf *nb)
{
	if (send_client_failure) {
		/* Test Send cmd fail */
		return send_client_failure;
	}

	memcpy(&res_hdr, nb->data, sizeof(res_hdr));
	res_hdr.nh_len = sys_be16_to_cpu(res_hdr.nh_len);
	res_hdr.nh_group = sys_be16_to_cpu(res_hdr.nh_group);
	res_hdr.nh_op += 1; /* Request to response */

	/* Validate Input data if callback is configured */
	if (rx_verify_cb) {
		rx_verify_cb(nb);
	}

	/* Free tx buf */
	net_buf_unref(nb);

	if (response_buf) {
		k_work_submit_to_queue(&smp_work_queue, &stub_work);
	}

	return 0;
}

static void smp_client_handle_reqs(struct k_work *work)
{
	if (response_buf) {
		smp_client_single_response(response_buf, &res_hdr);
	}
}

void stub_smp_client_transport_register(void)
{

	smpt_test.functions.output = smp_uart_tx_pkt;
	smpt_test.functions.get_mtu = smp_uart_get_mtu;

	smp_transport_init(&smpt_test);
	smp_client_transport.smpt = &smpt_test;
	smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT;
	smp_client_transport_register(&smp_client_transport);


	k_work_queue_init(&smp_work_queue);

	k_work_queue_start(&smp_work_queue, smp_stub_work_queue_stack,
			   K_THREAD_STACK_SIZEOF(smp_stub_work_queue_stack),
			   CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_THREAD_PRIO, &smp_work_queue_config);

	k_work_init(&stub_work, smp_client_handle_reqs);
}
