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

#include <zephyr/shell/shell.h>
#include <zephyr/init.h>
#include <string.h>
#include <stdio.h>
#include <zephyr/device.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/arch_interface.h>

extern const struct device __device_EARLY_start[];
extern const struct device __device_PRE_KERNEL_1_start[];
extern const struct device __device_PRE_KERNEL_2_start[];
extern const struct device __device_POST_KERNEL_start[];
extern const struct device __device_APPLICATION_start[];
extern const struct device __device_end[];

#ifdef CONFIG_SMP
extern const struct device __device_SMP_start[];
#endif

/* init levels, used as indices for levels array */
enum init_level {
	INIT_LEVEL_EARLY = 0,
	INIT_LEVEL_PRE_KERNEL_1,
	INIT_LEVEL_PRE_KERNEL_2,
	INIT_LEVEL_POST_KERNEL,
	INIT_LEVEL_APPLICATION,
#ifdef CONFIG_SMP
	INIT_LEVEL_SMP,
#endif
};

static const struct device *const levels[] = {
	__device_EARLY_start,
	__device_PRE_KERNEL_1_start,
	__device_PRE_KERNEL_2_start,
	__device_POST_KERNEL_start,
	__device_APPLICATION_start,
#ifdef CONFIG_SMP
	__device_SMP_start,
#endif
	/* End marker */
	__device_end,
};

static const char *get_device_name(const struct device *dev,
				   char *buf,
				   size_t len)
{
	const char *name = dev->name;

	if ((name == NULL) || (name[0] == 0)) {
		snprintf(buf, len, "[%p]", dev);
		name = buf;
	}

	return name;
}

static bool device_get_config_level(const struct shell *sh,
				    enum init_level level)
{
	const struct device *dev;
	bool devices = false;
	char buf[20];

	for (dev = levels[level]; dev < levels[level+1]; dev++) {
		if (device_is_ready(dev)) {
			devices = true;

			shell_fprintf(sh, SHELL_NORMAL, "- %s\n",
				      get_device_name(dev, buf, sizeof(buf)));
		}
	}
	return devices;
}

static int cmd_device_levels(const struct shell *sh,
			      size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);
	bool ret;

	shell_fprintf(sh, SHELL_NORMAL, "EARLY:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_EARLY);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}

	shell_fprintf(sh, SHELL_NORMAL, "PRE KERNEL 1:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_PRE_KERNEL_1);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}

	shell_fprintf(sh, SHELL_NORMAL, "PRE KERNEL 2:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_PRE_KERNEL_2);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}

	shell_fprintf(sh, SHELL_NORMAL, "POST_KERNEL:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_POST_KERNEL);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}

	shell_fprintf(sh, SHELL_NORMAL, "APPLICATION:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_APPLICATION);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}

#ifdef CONFIG_SMP
	shell_fprintf(sh, SHELL_NORMAL, "SMP:\n");
	ret = device_get_config_level(sh, INIT_LEVEL_SMP);
	if (ret == false) {
		shell_fprintf(sh, SHELL_NORMAL, "- None\n");
	}
#endif /* CONFIG_SMP */

	return 0;
}

struct cmd_device_list_visitor_context {
	const struct shell *shell;
	char *buf;
	size_t buf_size;
};

static int cmd_device_list_visitor(const struct device *dev,
				   void *context)
{
	const struct cmd_device_list_visitor_context *ctx = context;

	shell_fprintf(ctx->shell, SHELL_NORMAL, "  requires: %s\n",
		      get_device_name(dev, ctx->buf, ctx->buf_size));

	return 0;
}

static int cmd_device_list(const struct shell *sh,
			   size_t argc, char **argv)
{
	const struct device *devlist;
	size_t devcnt = z_device_get_all_static(&devlist);
	const struct device *devlist_end = devlist + devcnt;
	const struct device *dev;
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	shell_fprintf(sh, SHELL_NORMAL, "devices:\n");

	for (dev = devlist; dev < devlist_end; dev++) {
		char buf[20];
		const char *name = get_device_name(dev, buf, sizeof(buf));
		const char *state = "READY";

		shell_fprintf(sh, SHELL_NORMAL, "- %s", name);
		if (!device_is_ready(dev)) {
			state = "DISABLED";
		} else {
#ifdef CONFIG_PM_DEVICE
			enum pm_device_state st = PM_DEVICE_STATE_ACTIVE;
			int err = pm_device_state_get(dev, &st);

			if (!err) {
				state = pm_device_state_str(st);
			}
#endif /* CONFIG_PM_DEVICE */
		}

		shell_fprintf(sh, SHELL_NORMAL, " (%s)\n", state);
		if (!k_is_user_context()) {
			struct cmd_device_list_visitor_context ctx = {
				.shell = sh,
				.buf = buf,
				.buf_size = sizeof(buf),
			};

			(void)device_required_foreach(dev, cmd_device_list_visitor, &ctx);
		}
	}

	return 0;
}


SHELL_STATIC_SUBCMD_SET_CREATE(sub_device,
	SHELL_CMD(levels, NULL, "List configured devices by levels", cmd_device_levels),
	SHELL_CMD(list, NULL, "List configured devices", cmd_device_list),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_CMD_REGISTER(device, &sub_device, "Device commands", NULL);
