/*
 * Copyright (c) 2024 Astrolight
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/util.h>

#define TXRX_ARGV_BYTES     (1)
#define CONF_ARGV_DEV       (1)
#define CONF_ARGV_FREQUENCY (2)
#define CONF_ARGV_SETTINGS  (3)

#define CS_ARGV_GPIO_DEV    (1)
#define CS_ARGV_GPIO_PIN    (2)
#define CS_ARGV_GPIO_FLAGS  (3)

/* Maximum bytes we can write and read at once */
#define MAX_SPI_BYTES MIN((CONFIG_SHELL_ARGC_MAX - TXRX_ARGV_BYTES), 32)

static struct device *spi_device;
static struct spi_config config = {.frequency = 1000000,
				   .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8)};

static bool device_is_spi(const struct device *dev)
{
	return DEVICE_API_IS(spi, dev);
}

static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
	const struct device *dev = shell_device_filter(idx, device_is_spi);

	entry->syntax = (dev != NULL) ? dev->name : NULL;
	entry->handler = NULL;
	entry->help = NULL;
	entry->subcmd = NULL;
}

SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);

static int cmd_spi_transceive(const struct shell *ctx, size_t argc, char **argv)
{
	uint8_t rx_buffer[MAX_SPI_BYTES] = {0};
	uint8_t tx_buffer[MAX_SPI_BYTES] = {0};

	if (spi_device == NULL) {
		shell_error(ctx, "SPI device isn't configured. Use `spi conf`");
		return -ENODEV;
	}

	int bytes_to_send = argc - TXRX_ARGV_BYTES;

	for (int i = 0; i < bytes_to_send; i++) {
		tx_buffer[i] = strtol(argv[TXRX_ARGV_BYTES + i], NULL, 16);
	}

	const struct spi_buf tx_buffers = {.buf = tx_buffer, .len = bytes_to_send};
	const struct spi_buf rx_buffers = {.buf = rx_buffer, .len = bytes_to_send};

	const struct spi_buf_set tx_buf_set = {.buffers = &tx_buffers, .count = 1};
	const struct spi_buf_set rx_buf_set = {.buffers = &rx_buffers, .count = 1};

	int ret = spi_transceive(spi_device, &config, &tx_buf_set, &rx_buf_set);

	if (ret < 0) {
		shell_error(ctx, "spi_transceive returned %d", ret);
		return ret;
	}

	shell_print(ctx, "TX:");
	shell_hexdump(ctx, tx_buffer, bytes_to_send);

	shell_print(ctx, "RX:");
	shell_hexdump(ctx, rx_buffer, bytes_to_send);

	return ret;
}

static int cmd_spi_conf(const struct shell *ctx, size_t argc, char **argv)
{
	spi_operation_t operation = SPI_WORD_SET(8) | SPI_OP_MODE_MASTER;

	/* warning: initialization discards 'const' qualifier from pointer */
	/* target type */
	struct device *dev = (struct device *)shell_device_get_binding(argv[CONF_ARGV_DEV]);

	if (dev == NULL) {
		shell_error(ctx, "device %s not found.", argv[CONF_ARGV_DEV]);
		return -ENODEV;
	}

	uint32_t frequency = strtol(argv[CONF_ARGV_FREQUENCY], NULL, 10);

	if (!IN_RANGE(frequency, 100 * 1000, 80 * 1000 * 1000)) {
		shell_error(ctx, "frequency must be between 100000  and 80000000");
		return -EINVAL;
	}

	/* no settings */
	if (argc == (CONF_ARGV_FREQUENCY + 1)) {
		goto out;
	}

	char *opts = argv[CONF_ARGV_SETTINGS];
	bool all_opts_is_valid = true;

	while (*opts != '\0') {
		switch (*opts) {
		case 'o':
			operation |= SPI_MODE_CPOL;
			break;
		case 'h':
			operation |= SPI_MODE_CPHA;
			break;
		case 'l':
			operation |= SPI_TRANSFER_LSB;
			break;
		case 'T':
			operation |= SPI_FRAME_FORMAT_TI;
			break;
		default:
			all_opts_is_valid = false;
			shell_error(ctx, "invalid setting %c", *opts);
		}
		opts++;
	}

	if (!all_opts_is_valid) {
		return -EINVAL;
	}

out:
	config.frequency = frequency;
	config.operation = operation;
	spi_device = dev;

	return 0;
}

static int cmd_spi_conf_cs(const struct shell *ctx, size_t argc, char **argv)
{
	struct device *dev = (struct device *)shell_device_get_binding(argv[CS_ARGV_GPIO_DEV]);
	char *endptr = NULL;

	if (dev == NULL) {
		shell_error(ctx, "device %s not found.", argv[CS_ARGV_GPIO_DEV]);
		return -ENODEV;
	}

	int pin = strtol(argv[CS_ARGV_GPIO_PIN], &endptr, 10);

	if (endptr == argv[CS_ARGV_GPIO_PIN] || (pin < 0)) {
		shell_error(ctx, "invalid pin number: %s", argv[CS_ARGV_GPIO_PIN]);
		return -EINVAL;
	}

	config.cs.gpio.port = dev;
	config.cs.gpio.pin = pin;

	/* Include flags if provided */
	if (argc == (CS_ARGV_GPIO_FLAGS + 1)) {
		uint32_t flags = strtol(argv[CS_ARGV_GPIO_FLAGS], &endptr, 16);

		if (endptr == argv[CS_ARGV_GPIO_FLAGS]) {
			shell_error(ctx, "invalid gpio flags: %s", argv[CS_ARGV_GPIO_FLAGS]);
			return -EINVAL;
		}

		config.cs.gpio.dt_flags = flags;
	}

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_spi_cmds,
			       SHELL_CMD_ARG(conf, &dsub_device_name,
					     "Configure SPI\n"
					     "Usage: spi conf <device> <frequency> [<settings>]\n"
					     "<settings> - any sequence of letters:\n"
					     "o - SPI_MODE_CPOL\n"
					     "h - SPI_MODE_CPHA\n"
					     "l - SPI_TRANSFER_LSB\n"
					     "T - SPI_FRAME_FORMAT_TI\n"
					     "example: spi conf spi1 1000000 ol",
					     cmd_spi_conf, 3, 1),
			       SHELL_CMD_ARG(cs, &dsub_device_name,
					     "Assign CS GPIO to SPI device\n"
					     "Usage: spi cs <gpio-device> <pin> [<gpio flags>]"
					     "example: spi conf gpio1 3 0x01",
					     cmd_spi_conf_cs, 3, 1),
			       SHELL_CMD_ARG(transceive, NULL,
					     "Transceive data to and from an SPI device\n"
					     "Usage: spi transceive <TX byte 1> [<TX byte 2> ...]",
					     cmd_spi_transceive, 2, MAX_SPI_BYTES - 1),
			       SHELL_SUBCMD_SET_END);

SHELL_CMD_REGISTER(spi, &sub_spi_cmds, "SPI commands", NULL);
