/*
 * Copyright (c) 2018 Prevas A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/shell/shell.h>
#include <stdlib.h>
#include <zephyr/drivers/adc.h>
#include <ctype.h>
#include <zephyr/sys/util.h>
#include <zephyr/devicetree.h>

#if DT_HAS_COMPAT_STATUS_OKAY(atmel_sam_afec)
#define DT_DRV_COMPAT atmel_sam_afec
#elif DT_HAS_COMPAT_STATUS_OKAY(atmel_sam0_adc)
#define DT_DRV_COMPAT atmel_sam0_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(ite_it8xxx2_adc)
#define DT_DRV_COMPAT ite_it8xxx2_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(microchip_xec_adc)
#define DT_DRV_COMPAT microchip_xec_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(microchip_xec_adc_v2)
#define DT_DRV_COMPAT microchip_xec_adc_v2
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_adc)
#define DT_DRV_COMPAT nordic_nrf_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_saadc)
#define DT_DRV_COMPAT nordic_nrf_saadc
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_mcux_12b1msps_sar)
#define DT_DRV_COMPAT nxp_mcux_12b1msps_sar
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_adc12)
#define DT_DRV_COMPAT nxp_kinetis_adc12
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_adc16)
#define DT_DRV_COMPAT nxp_kinetis_adc16
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_adc)
#define DT_DRV_COMPAT st_stm32_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_npcx_adc)
#define DT_DRV_COMPAT nuvoton_npcx_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(ti_cc32xx_adc)
#define DT_DRV_COMPAT ti_cc32xx_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(raspberrypi_pico_adc)
#define DT_DRV_COMPAT raspberrypi_pico_adc
#elif DT_HAS_COMPAT_STATUS_OKAY(zephyr_adc_emul)
#define DT_DRV_COMPAT zephyr_adc_emul
#else
#error No known devicetree compatible match for ADC shell
#endif

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(adc_shell);

#define CMD_HELP_ACQ_TIME 			\
	"Configure acquisition time."		\
	"\nUsage: acq_time <time> <unit>"	\
	"\nunits: us, ns, ticks\n"

#define CMD_HELP_CHANNEL			\
	"Configure ADC channel\n"		\

#define CMD_HELP_CH_ID				\
	"Configure channel id\n"		\
	"Usage: id <channel_id>\n"

#define CMD_HELP_CH_NEG				\
	"Configure channel negative input\n"	\
	"Usage: negative <negative_input_id>\n"

#define CMD_HELP_CH_POS				\
	"Configure channel positive input\n"	\
	"Usage: positive <positive_input_id>\n"

#define CMD_HELP_READ				\
	"Read adc value\n"			\
	"Usage: read <channel>\n"

#define CMD_HELP_RES				\
	"Configure resolution\n"		\
	"Usage: resolution <resolution>\n"

#define CMD_HELP_REF	"Configure reference\n"
#define CMD_HELP_GAIN	"Configure gain.\n"
#define CMD_HELP_PRINT	"Print current configuration"

#define DEVICES(n) DEVICE_DT_INST_GET(n),
#define ADC_HDL_LIST_ENTRY(dev_)					\
	{								\
		.dev = dev_,						\
		.channel_config = {					\
			.gain = ADC_GAIN_1,				\
			.reference = ADC_REF_INTERNAL,			\
			.acquisition_time = ADC_ACQ_TIME_DEFAULT,	\
			.channel_id = 0,				\
		},							\
		.resolution = 0,					\
	}

#define INIT_MACRO() DT_INST_FOREACH_STATUS_OKAY(DEVICES) NULL

#define CHOSEN_STR_LEN 20
static char chosen_reference[CHOSEN_STR_LEN + 1] = "INTERNAL";
static char chosen_gain[CHOSEN_STR_LEN + 1] = "1";

/* This table size is = ADC devices count + 1 (NA). */
static struct adc_hdl {
	const struct device *dev;
	struct adc_channel_cfg channel_config;
	uint8_t resolution;
} adc_list[] = {
	FOR_EACH(ADC_HDL_LIST_ENTRY, (,), INIT_MACRO())
};

static struct adc_hdl *get_adc(const char *device_label)
{
	for (int i = 0; i < ARRAY_SIZE(adc_list); i++) {
		if (!strcmp(device_label, adc_list[i].dev->name)) {
			return &adc_list[i];
		}
	}

	/* This will never happen because ADC was prompted by shell */
	__ASSERT_NO_MSG(false);
	return NULL;
}

static int cmd_adc_ch_id(const struct shell *shell, size_t argc, char **argv)
{
	/* -2: index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-2]);
	int retval = 0;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	if (!isdigit((unsigned char)argv[1][0])) {
		shell_error(shell, "<channel> must be digits");
		return -EINVAL;
	}

	adc->channel_config.channel_id = (uint8_t)strtol(argv[1], NULL, 10);
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
}

static int cmd_adc_ch_neg(const struct shell *shell, size_t argc, char **argv)
{
#if CONFIG_ADC_CONFIGURABLE_INPUTS
	/* -2: index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-2]);
	int retval = 0;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	if (!isdigit((unsigned char)argv[1][0])) {
		shell_error(shell, "<negative input> must be digits");
		return -EINVAL;
	}

	adc->channel_config.input_negative = (uint8_t)strtol(argv[1], NULL, 10);
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
#else
	return -EINVAL;
#endif
}

static int cmd_adc_ch_pos(const struct shell *shell, size_t argc, char **argv)
{
#if CONFIG_ADC_CONFIGURABLE_INPUTS
	/* -2: index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-2]);
	int retval = 0;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	if (!isdigit((unsigned char)argv[1][0])) {
		shell_error(shell, "<positive input> must be digits");
		return -EINVAL;
	}

	adc->channel_config.input_positive = (uint8_t)strtol(argv[1], NULL, 10);
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
#else
	return -EINVAL;
#endif
}

static int cmd_adc_gain(const struct shell *shell, size_t argc, char **argv,
			void *data)
{
	/* -2: index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-2]);
	enum adc_gain gain = (enum adc_gain)data;
	int retval = -EINVAL;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	adc->channel_config.gain = gain;
	int len = strlen(argv[0]) > CHOSEN_STR_LEN ? CHOSEN_STR_LEN
						   : strlen(argv[0]);
	memcpy(chosen_gain, argv[0], len);
	chosen_gain[len] = '\0';
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
}

static int cmd_adc_acq(const struct shell *shell, size_t argc, char **argv)
{
	/* -1 index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-1]);
	uint16_t acq_time;
	int retval;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	if (!isdigit((unsigned char)argv[1][0])) {
		shell_error(shell, "<time> must be digits");
		return -EINVAL;
	}

	acq_time = (uint16_t)strtol(argv[1], NULL, 10);
	if (!strcmp(argv[2], "us")) {
		adc->channel_config.acquisition_time =
			ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, acq_time);
	} else if (!strcmp(argv[2], "ns")) {
		adc->channel_config.acquisition_time =
			ADC_ACQ_TIME(ADC_ACQ_TIME_NANOSECONDS, acq_time);
	} else if (!strcmp(argv[2], "ticks")) {
		adc->channel_config.acquisition_time =
			ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, acq_time);
	} else {
		adc->channel_config.acquisition_time =
			ADC_ACQ_TIME_DEFAULT;
	}
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
}
static int cmd_adc_reso(const struct shell *shell, size_t argc, char **argv)
{
	/* -1 index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-1]);
	int retval;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	if (!isdigit((unsigned char)argv[1][0])) {
		shell_error(shell, "<resolution> must be digits");
		return -EINVAL;
	}

	adc->resolution = (uint8_t)strtol(argv[1], NULL, 10);
	retval = adc_channel_setup(adc->dev, &adc->channel_config);

	return retval;
}

static int cmd_adc_ref(const struct shell *shell, size_t argc, char **argv,
		       void *data)
{
	/* -2 index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-2]);
	enum adc_reference reference = (enum adc_reference)data;
	int retval = -EINVAL;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	int len = strlen(argv[0]) > CHOSEN_STR_LEN ? CHOSEN_STR_LEN
						   : strlen(argv[0]);
	memcpy(chosen_reference, argv[0], len);
	chosen_reference[len] = '\0';

	adc->channel_config.reference = reference;
	retval = adc_channel_setup(adc->dev, &adc->channel_config);
	LOG_DBG("Channel setup returned %i\n", retval);

	return retval;
}

#define BUFFER_SIZE 1
static int cmd_adc_read(const struct shell *shell, size_t argc, char **argv)
{
	uint8_t adc_channel_id = strtol(argv[1], NULL, 10);
	/* -1 index of adc label name */
	struct adc_hdl *adc = get_adc(argv[-1]);
	uint16_t m_sample_buffer[BUFFER_SIZE];
	int retval;

	if (!device_is_ready(adc->dev)) {
		shell_error(shell, "ADC device not ready");
		return -ENODEV;
	}

	adc->channel_config.channel_id = adc_channel_id;
	const struct adc_sequence sequence = {
		.channels	= BIT(adc->channel_config.channel_id),
		.buffer		= m_sample_buffer,
		.buffer_size	= sizeof(m_sample_buffer),
		.resolution	= adc->resolution,
	};

	retval = adc_read(adc->dev, &sequence);
	if (retval >= 0) {
		shell_print(shell, "read: %i", m_sample_buffer[0]);
	}

	return retval;
}

static int cmd_adc_print(const struct shell *shell, size_t argc, char **argv)
{
	/* -1 index of ADC label name */
	struct adc_hdl *adc = get_adc(argv[-1]);

	shell_print(shell, "%s:\n"
			   "Gain: %s\n"
			   "Reference: %s\n"
			   "Acquisition Time: %u\n"
			   "Channel ID: %u\n"
			   "Resolution: %u",
			   adc->dev->name,
			   chosen_gain,
			   chosen_reference,
			   adc->channel_config.acquisition_time,
			   adc->channel_config.channel_id,
			   adc->resolution);
	return 0;
}

SHELL_SUBCMD_DICT_SET_CREATE(sub_ref_cmds, cmd_adc_ref,
	(VDD_1, ADC_REF_VDD_1),
	(VDD_1_2, ADC_REF_VDD_1_2),
	(VDD_1_3, ADC_REF_VDD_1_3),
	(VDD_1_4, ADC_REF_VDD_1_4),
	(INTERNAL, ADC_REF_INTERNAL),
	(EXTERNAL_0, ADC_REF_EXTERNAL0),
	(EXTERNAL_1, ADC_REF_EXTERNAL1)
);

SHELL_SUBCMD_DICT_SET_CREATE(sub_gain_cmds, cmd_adc_gain,
	(GAIN_1_6, ADC_GAIN_1_6),
	(GAIN_1_5, ADC_GAIN_1_5),
	(GAIN_1_4, ADC_GAIN_1_4),
	(GAIN_1_3, ADC_GAIN_1_3),
	(GAIN_1_2, ADC_GAIN_1_2),
	(GAIN_2_3, ADC_GAIN_2_3),
	(GAIN_1, ADC_GAIN_1),
	(GAIN_2, ADC_GAIN_2),
	(GAIN_3, ADC_GAIN_3),
	(GAIN_4, ADC_GAIN_4),
	(GAIN_8, ADC_GAIN_8),
	(GAIN_16, ADC_GAIN_16),
	(GAIN_32, ADC_GAIN_32),
	(GAIN_64, ADC_GAIN_64)
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_channel_cmds,
	SHELL_CMD_ARG(id, NULL, CMD_HELP_CH_ID, cmd_adc_ch_id, 2, 0),
	SHELL_COND_CMD_ARG(CONFIG_ADC_CONFIGURABLE_INPUTS,
		negative, NULL, CMD_HELP_CH_NEG, cmd_adc_ch_neg, 2, 0),
	SHELL_COND_CMD_ARG(CONFIG_ADC_CONFIGURABLE_INPUTS,
		positive, NULL, CMD_HELP_CH_POS, cmd_adc_ch_pos, 2, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_adc_cmds,
	/* Alphabetically sorted. */
	SHELL_CMD_ARG(acq_time, NULL, CMD_HELP_ACQ_TIME, cmd_adc_acq, 3, 0),
	SHELL_CMD_ARG(channel, &sub_channel_cmds, CMD_HELP_CHANNEL, NULL, 3, 0),
	SHELL_CMD(gain, &sub_gain_cmds, CMD_HELP_GAIN, NULL),
	SHELL_CMD_ARG(print, NULL, CMD_HELP_PRINT, cmd_adc_print, 1, 0),
	SHELL_CMD_ARG(read, NULL, CMD_HELP_READ, cmd_adc_read, 2, 0),
	SHELL_CMD(reference, &sub_ref_cmds, CMD_HELP_REF, NULL),
	SHELL_CMD_ARG(resolution, NULL, CMD_HELP_RES, cmd_adc_reso, 2, 0),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

static void cmd_adc_dev_get(size_t idx, struct shell_static_entry *entry)
{
	/* -1 because the last element in the list is a "list terminator" */
	if (idx < ARRAY_SIZE(adc_list) - 1) {
		entry->syntax  = adc_list[idx].dev->name;
		entry->handler = NULL;
		entry->subcmd  = &sub_adc_cmds;
		entry->help    = "Select subcommand for ADC property label.\n";
	} else {
		entry->syntax  = NULL;
	}
}
SHELL_DYNAMIC_CMD_CREATE(sub_adc_dev, cmd_adc_dev_get);

SHELL_CMD_REGISTER(adc, &sub_adc_dev, "ADC commands", NULL);
