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

#include <sys/printk.h>
#include <shell/shell.h>
#include <drivers/hwinfo.h>
#include <zephyr/types.h>
#include <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 supporte");
	}

	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_get_device_id, 1, 0),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

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