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

#include <zephyr/shell/shell.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_CMD_CNT (20u)
#define MAX_CMD_LEN (33u)

/* buffer holding dynamically created user commands */
static char dynamic_cmd_buffer[MAX_CMD_CNT][MAX_CMD_LEN];
/* commands counter */
static uint8_t dynamic_cmd_cnt;

typedef int cmp_t(const void *, const void *);
extern void qsort(void *a, size_t n, size_t es, cmp_t *cmp);

/* function required by qsort */
static int string_cmp(const void *p_a, const void *p_b)
{
	return strcmp((const char *)p_a, (const char *)p_b);
}

static int cmd_dynamic_add(const struct shell *shell,
			   size_t argc, char **argv)
{
	uint16_t cmd_len;
	uint8_t idx;

	ARG_UNUSED(argc);

	if (dynamic_cmd_cnt >= MAX_CMD_CNT) {
		shell_error(shell, "command limit reached");
		return -ENOEXEC;
	}

	cmd_len = strlen(argv[1]);

	if (cmd_len >= MAX_CMD_LEN) {
		shell_error(shell, "too long command");
		return -ENOEXEC;
	}

	for (idx = 0U; idx < cmd_len; idx++) {
		if (!isalnum((int)(argv[1][idx]))) {
			shell_error(shell,
				    "bad command name - please use only"
				    " alphanumerical characters");
			return -ENOEXEC;
		}
	}

	for (idx = 0U; idx < MAX_CMD_CNT; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			shell_error(shell, "duplicated command");
			return -ENOEXEC;
		}
	}

	sprintf(dynamic_cmd_buffer[dynamic_cmd_cnt++], "%s", argv[1]);

	qsort(dynamic_cmd_buffer, dynamic_cmd_cnt,
	      sizeof(dynamic_cmd_buffer[0]), string_cmp);

	shell_print(shell, "command added successfully");

	return 0;
}

static int cmd_dynamic_execute(const struct shell *shell,
			       size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	for (uint8_t idx = 0; idx <  dynamic_cmd_cnt; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			shell_print(shell, "dynamic command: %s", argv[1]);
			return 0;
		}
	}

	shell_error(shell, "%s: unknown parameter: %s", argv[0], argv[1]);

	return -ENOEXEC;
}

static int cmd_dynamic_remove(const struct shell *shell, size_t argc,
			      char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	for (uint8_t idx = 0; idx <  dynamic_cmd_cnt; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			if (idx == MAX_CMD_CNT - 1) {
				dynamic_cmd_buffer[idx][0] = '\0';
			} else {
				memmove(dynamic_cmd_buffer[idx],
					dynamic_cmd_buffer[idx + 1],
					sizeof(dynamic_cmd_buffer[idx]) *
					(dynamic_cmd_cnt - idx));
			}

			--dynamic_cmd_cnt;
			shell_print(shell, "command removed successfully");
			return 0;
		}
	}
	shell_error(shell, "did not find command: %s", argv[1]);

	return -ENOEXEC;
}

static int cmd_dynamic_show(const struct shell *shell,
			    size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (dynamic_cmd_cnt == 0U) {
		shell_warn(shell, "Please add some commands first.");
		return -ENOEXEC;
	}

	shell_print(shell, "Dynamic command list:");

	for (uint8_t i = 0; i < dynamic_cmd_cnt; i++) {
		shell_print(shell, "[%3d] %s", i, dynamic_cmd_buffer[i]);
	}

	return 0;
}

/* dynamic command creation */
static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry)
{
	if (idx < dynamic_cmd_cnt) {
		/* m_dynamic_cmd_buffer must be sorted alphabetically to ensure
		 * correct CLI completion
		 */
		entry->syntax = dynamic_cmd_buffer[idx];
		entry->handler  = NULL;
		entry->subcmd = NULL;
		entry->help = "Show dynamic command name.";
	} else {
		/* if there are no more dynamic commands available syntax
		 * must be set to NULL.
		 */
		entry->syntax = NULL;
	}
}

SHELL_DYNAMIC_CMD_CREATE(m_sub_dynamic_set, dynamic_cmd_get);
SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_dynamic,
	SHELL_CMD_ARG(add, NULL,
		"Add a new dynamic command.\nExample usage: [ dynamic add test "
		"] will add a dynamic command 'test'.\nIn this example, command"
		" name length is limited to 32 chars. You can add up to 20"
		" commands. Commands are automatically sorted to ensure correct"
		" shell completion.",
		cmd_dynamic_add, 2, 0),
	SHELL_CMD_ARG(execute, &m_sub_dynamic_set,
		"Execute a command.", cmd_dynamic_execute, 2, 0),
	SHELL_CMD_ARG(remove, &m_sub_dynamic_set,
		"Remove a command.", cmd_dynamic_remove, 2, 0),
	SHELL_CMD_ARG(show, NULL,
		"Show all added dynamic commands.", cmd_dynamic_show, 1, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic,
		   "Demonstrate dynamic command usage.", NULL);
