/*
 * Copyright (c) 2023 Fabian Blatz <fabianblatz@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/shell/shell.h>
#include <lvgl.h>
#include <zephyr/autoconf.h>

#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
#include "lvgl_mem.h"
#endif

#ifdef CONFIG_LV_USE_MONKEY
static lv_monkey_t *lvgl_monkeys[CONFIG_LV_Z_MAX_MONKEY_COUNT];

static const char *lvgl_monkey_indev_as_string(lv_monkey_t *monkey)
{
	lv_indev_t *input_device;

	input_device = lv_monkey_get_indev(monkey);
	if (!input_device) {
		return "unknown";
	}

	switch (lv_indev_get_type(input_device)) {
	case LV_INDEV_TYPE_POINTER:
		return "pointer";
	case LV_INDEV_TYPE_KEYPAD:
		return "keypad";
	case LV_INDEV_TYPE_BUTTON:
		return "button";
	case LV_INDEV_TYPE_ENCODER:
		return "encoder";
	default:
		return "unknown";
	}
}

static int lvgl_monkey_indev_from_string(const char *str, lv_indev_type_t *input_device)
{
	if (strcmp(str, "pointer") == 0) {
		*input_device = LV_INDEV_TYPE_POINTER;
	} else if (strcmp(str, "keypad") == 0) {
		*input_device = LV_INDEV_TYPE_KEYPAD;
	} else if (strcmp(str, "button") == 0) {
		*input_device = LV_INDEV_TYPE_BUTTON;
	} else if (strcmp(str, "encoder") == 0) {
		*input_device = LV_INDEV_TYPE_ENCODER;
	} else {
		return -EINVAL;
	}
	return 0;
}

static void dump_monkey_info(const struct shell *sh)
{
	shell_print(sh, "id   device    active");
	for (size_t i = 0; i < CONFIG_LV_Z_MAX_MONKEY_COUNT; i++) {
		if (lvgl_monkeys[i] != NULL) {
			shell_print(sh, "%-4zu %-9s %-3s", i,
				    lvgl_monkey_indev_as_string(lvgl_monkeys[i]),
				    lv_monkey_get_enable(lvgl_monkeys[i]) ? "yes" : "no");
		}
	}
}

static int cmd_lvgl_monkey(const struct shell *sh, size_t argc, char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	dump_monkey_info(sh);
	shell_print(sh, "");
	shell_help(sh);

	return SHELL_CMD_HELP_PRINTED;
}

static int cmd_lvgl_monkey_create(const struct shell *sh, size_t argc, char *argv[])
{
	bool created_monkey = false;
	lv_monkey_config_t default_config;

	lv_monkey_config_init(&default_config);

	if (argc == 2) {
		if (lvgl_monkey_indev_from_string(argv[1], &default_config.type) < 0) {
			shell_error(sh, "Invalid monkey input device %s", argv[1]);
			shell_help(sh);
			return SHELL_CMD_HELP_PRINTED;
		}
	}

	for (size_t i = 0; i < CONFIG_LV_Z_MAX_MONKEY_COUNT; i++) {
		if (lvgl_monkeys[i] == NULL) {
			lvgl_monkeys[i] = lv_monkey_create(&default_config);
			lv_monkey_set_enable(lvgl_monkeys[i], true);
			created_monkey = true;
			break;
		}
	}

	if (!created_monkey) {
		shell_error(sh, "Error creating monkey instance");
		return -ENOSPC;
	}

	dump_monkey_info(sh);

	return 0;
}

static int cmd_lvgl_monkey_set(const struct shell *sh, size_t argc, char *argv[])
{
	int index;

	index = atoi(argv[1]);
	if (index < 0 || index >= CONFIG_LV_Z_MAX_MONKEY_COUNT || lvgl_monkeys[index] == NULL) {
		shell_error(sh, "Invalid monkey index");
		return -ENOEXEC;
	}

	if (strcmp(argv[2], "active") == 0) {
		lv_monkey_set_enable(lvgl_monkeys[index], true);
	} else if (strcmp(argv[2], "inactive") == 0) {
		lv_monkey_set_enable(lvgl_monkeys[index], false);
	} else {
		shell_error(sh, "Invalid monkey state %s", argv[2]);
		shell_help(sh);
		return SHELL_CMD_HELP_PRINTED;
	}

	dump_monkey_info(sh);

	return 0;
}
#endif /* CONFIG_LV_USE_MONKEY */

static int cmd_lvgl_stats(const struct shell *sh, size_t argc, char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	shell_help(sh);
	return SHELL_CMD_HELP_PRINTED;
}

static int cmd_lvgl_stats_memory(const struct shell *sh, size_t argc, char *argv[])
{
#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
	bool dump_chunks = false;

	if (argc == 2) {
		if (strcmp(argv[1], "-c") == 0) {
			dump_chunks = true;
		} else {
			shell_error(sh, "unsupported option %s", argv[1]);
			shell_help(sh);
			return SHELL_CMD_HELP_PRINTED;
		}
	}

	lvgl_print_heap_info(dump_chunks);
	return 0;
#else
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);
	shell_error(sh, "Set CONFIG_LV_Z_MEM_POOL_SYS_HEAP to enable memory statistics support.");
	return -ENOTSUP;
#endif
}

SHELL_STATIC_SUBCMD_SET_CREATE(lvgl_cmd_stats,
			       SHELL_CMD_ARG(memory, NULL,
					     SHELL_HELP("Show LVGL memory statistics",
							"[-c]\n"
							"-c  dump chunk information"),
					     cmd_lvgl_stats_memory, 1, 1),
			       SHELL_SUBCMD_SET_END);

#ifdef CONFIG_LV_USE_MONKEY
SHELL_STATIC_SUBCMD_SET_CREATE(
	lvgl_cmd_monkey,
	SHELL_CMD_ARG(create, NULL,
		      SHELL_HELP("Create a new monkey instance (default: pointer)",
				 "[pointer|keypad|button|encoder]"),
		      cmd_lvgl_monkey_create, 1, 1),
	SHELL_CMD_ARG(set, NULL,
		      SHELL_HELP("Activate/deactivate a monkey instance",
				 "<index> <active|inactive>"),
		      cmd_lvgl_monkey_set, 3, 0),
	SHELL_SUBCMD_SET_END);
#endif /* CONFIG_LV_USE_MONKEY */

SHELL_STATIC_SUBCMD_SET_CREATE(
	lvgl_cmds, SHELL_CMD(stats, &lvgl_cmd_stats, "Show LVGL statistics", cmd_lvgl_stats),
#ifdef CONFIG_LV_USE_MONKEY
	SHELL_CMD(monkey, &lvgl_cmd_monkey, "LVGL monkey testing", cmd_lvgl_monkey),
#endif /* CONFIG_LV_USE_MONKEY */
	SHELL_SUBCMD_SET_END);

SHELL_CMD_REGISTER(lvgl, &lvgl_cmds, "LVGL shell commands", NULL);
