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

#include <zephyr/ztest.h>
#include <zephyr/net/buf.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/transport/smp_dummy.h>
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
#include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
#include <zcbor_common.h>
#include <zcbor_decode.h>
#include <zcbor_encode.h>
#include <mgmt/mcumgr/util/zcbor_bulk.h>
#include <version.h>
#include <string.h>
#include <smp_internal.h>
#include "smp_test_util.h"

#define SMP_RESPONSE_WAIT_TIME 3
#define ZCBOR_BUFFER_SIZE 64
#define OUTPUT_BUFFER_SIZE 64
#define ZCBOR_HISTORY_ARRAY_SIZE 4

/* Test sets */
enum {
	CB_NOTIFICATION_TEST_CALLBACK_DISABLED,
	CB_NOTIFICATION_TEST_CALLBACK_ENABLED,
	CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY,

	CB_NOTIFICATION_TEST_SET_COUNT
};

static struct net_buf *nb;

struct state {
	uint8_t test_set;
};

static struct state test_state = {
	.test_set = 0,
};

static bool cmd_recv_got;
static bool cmd_status_got;
static bool cmd_done_got;
static bool cmd_other_got;

/* Responses to commands */

static int32_t mgmt_event_cmd_callback(uint32_t event, int32_t rc, bool *abort_more,
						void *data, size_t data_size)
{
	if (event == MGMT_EVT_OP_CMD_RECV) {
		cmd_recv_got = true;
	} else if (event == MGMT_EVT_OP_CMD_STATUS) {
		cmd_status_got = true;
	} else if (event == MGMT_EVT_OP_CMD_DONE) {
		cmd_done_got = true;
	} else {
		cmd_other_got = true;
	}

	return MGMT_ERR_EOK;
}

static struct mgmt_callback mgmt_event_callback = {
	.callback = mgmt_event_cmd_callback,
	.event_id = (MGMT_EVT_OP_CMD_RECV | MGMT_EVT_OP_CMD_STATUS | MGMT_EVT_OP_CMD_DONE),
};

static void *setup_callbacks(void)
{
	mgmt_callback_register(&mgmt_event_callback);
	return NULL;
}

static void destroy_callbacks(void *p)
{
	mgmt_callback_unregister(&mgmt_event_callback);
}

ZTEST(callback_disabled, test_notifications_disabled)
{
	uint8_t buffer[ZCBOR_BUFFER_SIZE];
	uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
	bool ok;
	uint16_t buffer_size;
	zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	bool received;

	memset(buffer, 0, sizeof(buffer));
	memset(buffer_out, 0, sizeof(buffer_out));
	buffer_size = 0;
	memset(zse, 0, sizeof(zse));
	memset(zsd, 0, sizeof(zsd));

	zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);

	ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
	zassert_true(ok, "Expected packet creation to be successful\n");

	/* Enable dummy SMP backend and ready for usage */
	smp_dummy_enable();
	smp_dummy_clear_state();

	/* Send query command to dummy SMP backend */
	(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
	smp_dummy_add_data();

	/* For a short duration to see if response has been received */
	received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);

	zassert_true(received, "Expected to receive data but timed out\n");

	/* Retrieve response buffer */
	nb = smp_dummy_get_outgoing();
	smp_dummy_disable();

	/* Check events */
	zassert_false(cmd_recv_got, "Did not expect received command callback\n");
	zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
	zassert_false(cmd_done_got, "Did not expect done command callback\n");
	zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}

ZTEST(callback_enabled, test_notifications_enabled)
{
	uint8_t buffer[ZCBOR_BUFFER_SIZE];
	uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
	bool ok;
	uint16_t buffer_size;
	zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	bool received;

	memset(buffer, 0, sizeof(buffer));
	memset(buffer_out, 0, sizeof(buffer_out));
	buffer_size = 0;
	memset(zse, 0, sizeof(zse));
	memset(zsd, 0, sizeof(zsd));

	zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);

	ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
	zassert_true(ok, "Expected packet creation to be successful\n");

	/* Enable dummy SMP backend and ready for usage */
	smp_dummy_enable();
	smp_dummy_clear_state();

	/* Send query command to dummy SMP backend */
	(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
	smp_dummy_add_data();

	/* For a short duration to see if response has been received */
	received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);

	zassert_true(received, "Expected to receive data but timed out\n");

	/* Retrieve response buffer */
	nb = smp_dummy_get_outgoing();
	smp_dummy_disable();

	/* Check events */
	zassert_true(cmd_recv_got, "Expected received command callback\n");
	zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
	zassert_true(cmd_done_got, "Expected done command callback\n");
	zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}

ZTEST(callback_disabled_verify, test_notifications_disabled_verify)
{
	uint8_t buffer[ZCBOR_BUFFER_SIZE];
	uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
	bool ok;
	uint16_t buffer_size;
	zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
	bool received;

	memset(buffer, 0, sizeof(buffer));
	memset(buffer_out, 0, sizeof(buffer_out));
	buffer_size = 0;
	memset(zse, 0, sizeof(zse));
	memset(zsd, 0, sizeof(zsd));

	zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);

	ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size);
	zassert_true(ok, "Expected packet creation to be successful\n");

	/* Enable dummy SMP backend and ready for usage */
	smp_dummy_enable();
	smp_dummy_clear_state();

	/* Send query command to dummy SMP backend */
	(void)smp_dummy_tx_pkt(buffer_out, buffer_size);
	smp_dummy_add_data();

	/* For a short duration to see if response has been received */
	received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);

	zassert_true(received, "Expected to receive data but timed out\n");

	/* Retrieve response buffer */
	nb = smp_dummy_get_outgoing();
	smp_dummy_disable();

	/* Check events */
	zassert_false(cmd_recv_got, "Did not expect received command callback\n");
	zassert_false(cmd_status_got, "Did not expect IMG status callback\n");
	zassert_false(cmd_done_got, "Did not expect done command callback\n");
	zassert_false(cmd_other_got, "Did not expect other callback(s)\n");
}

static void cleanup_test(void *p)
{
	if (nb != NULL) {
		net_buf_unref(nb);
		nb = NULL;
	}

	cmd_recv_got = false;
	cmd_status_got = false;
	cmd_done_got = false;
	cmd_other_got = false;
}

void test_main(void)
{
	while (test_state.test_set < CB_NOTIFICATION_TEST_SET_COUNT) {
		ztest_run_all(&test_state);
		++test_state.test_set;
	}

	ztest_verify_all_test_suites_ran();
}

static bool callback_disabled_predicate(const void *state)
{
	return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED;
}

static bool callback_enabled_predicate(const void *state)
{
	return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_ENABLED;
}

static bool callback_disabled_verify_predicate(const void *state)
{
	return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY;
}

ZTEST_SUITE(callback_disabled, callback_disabled_predicate, NULL, NULL, cleanup_test, NULL);
ZTEST_SUITE(callback_enabled, callback_enabled_predicate, setup_callbacks, NULL, cleanup_test,
	    destroy_callbacks);
ZTEST_SUITE(callback_disabled_verify, callback_disabled_verify_predicate, NULL, NULL,
	    cleanup_test, NULL);
