/*
 * Copyright (c) 2019 Alexander Wachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/sys/printk.h>
#include <zephyr/shell/shell.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/types.h>
#include <zephyr/logging/log.h>

static int cmd_get_device_id(const struct shell *sh, size_t argc, char **argv)
{
	uint8_t dev_id[16];
	ssize_t length;
	int i;

	length = hwinfo_get_device_id(dev_id, sizeof(dev_id));

	if (length == -ENOTSUP) {
		shell_error(sh, "Not supported by hardware");
		return -ENOTSUP;
	} else if (length < 0) {
		shell_error(sh, "Error: %zd", length);
		return length;
	}

	shell_fprintf(sh, SHELL_NORMAL, "Length: %zd\n", length);
	shell_fprintf(sh, SHELL_NORMAL, "ID: 0x");

	for (i = 0 ; i < length ; i++) {
		shell_fprintf(sh, SHELL_NORMAL, "%02x", dev_id[i]);
	}

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

	return 0;
}

static inline const char *cause_to_string(uint32_t cause)
{
	switch (cause) {
	case RESET_PIN:
		return "pin";

	case RESET_SOFTWARE:
		return "software";

	case RESET_BROWNOUT:
		return "brownout";

	case RESET_POR:
		return "power-on reset";

	case RESET_WATCHDOG:
		return "watchdog";

	case RESET_DEBUG:
		return "debug";

	case RESET_SECURITY:
		return "security";

	case RESET_LOW_POWER_WAKE:
		return "low power wake-up";

	case RESET_CPU_LOCKUP:
		return "CPU lockup";

	case RESET_PARITY:
		return "parity error";

	case RESET_PLL:
		return "PLL error";

	case RESET_CLOCK:
		return "clock";

	default:
		return "unknown";
	}
}

static void print_all_reset_causes(const struct shell *sh, uint32_t cause)
{
	for (uint32_t cause_mask = 1; cause_mask; cause_mask <<= 1) {
		if (cause & cause_mask) {
			shell_print(sh, "- %s",
				    cause_to_string(cause & cause_mask));
		}
	}
}

static int cmd_show_reset_cause(const struct shell *sh, size_t argc,
				char **argv)
{
	int res;
	uint32_t cause;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	res = hwinfo_get_reset_cause(&cause);
	if (res == -ENOTSUP) {
		shell_error(sh, "Not supported by hardware");
		return res;
	} else if (res != 0) {
		shell_error(sh, "Error reading the cause [%d]", res);
		return res;
	}

	if (cause != 0) {
		shell_print(sh, "reset caused by:");
		print_all_reset_causes(sh, cause);
	} else {
		shell_print(sh, "No reset cause set");
	}

	return 0;
}

static int cmd_clear_reset_cause(const struct shell *sh, size_t argc,
				 char **argv)
{
	int res;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	res = hwinfo_clear_reset_cause();
	if (res == -ENOTSUP) {
		shell_error(sh, "Not supported by hardware");
	} else if (res != 0) {
		shell_error(sh, "Error clearing the reset causes [%d]", res);
		return res;
	}

	return 0;
}

static int cmd_supported_reset_cause(const struct shell *sh, size_t argc,
				     char **argv)
{
	uint32_t cause;
	int res;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	res = hwinfo_get_supported_reset_cause(&cause);
	if (res == -ENOTSUP) {
		shell_error(sh, "Not supported by hardware");
	} else if (res != 0) {
		shell_error(sh, "Could not get the supported reset causes [%d]", res);
		return res;
	}

	if (cause != 0) {
		shell_print(sh, "supported reset causes:");
		print_all_reset_causes(sh, cause);
	} else {
		shell_print(sh, "No causes supported");
	}

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_reset_cause,
	SHELL_CMD_ARG(show, NULL, "Show persistent reset causes",
		      cmd_show_reset_cause, 1, 0),
	SHELL_CMD_ARG(clear, NULL, "Clear all persistent reset causes",
		      cmd_clear_reset_cause, 1, 0),
	SHELL_CMD_ARG(supported, NULL,
		      "Get a list of all supported reset causes",
		      cmd_supported_reset_cause, 1, 0),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_hwinfo,
	SHELL_CMD_ARG(devid, NULL, "Show device id", cmd_get_device_id, 1, 0),
	SHELL_CMD_ARG(reset_cause, &sub_reset_cause, "Reset cause commands",
		      cmd_show_reset_cause, 1, 0),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_CMD_ARG_REGISTER(hwinfo, &sub_hwinfo, "HWINFO commands", NULL, 2, 0);
