/*
 * Copyright (c) 2023 Centralp
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/audio/codec.h>

#define CODEC_START_HELP                                                                           \
	"Start output audio playback. Syntax:\n"                                                   \
	"<device>"

#define CODEC_STOP_HELP                                                                            \
	"Stop output audio playback. Syntax:\n"                                                    \
	"<device>"

#define CODEC_SET_PROP_HELP                                                                        \
	"Set a codec property. Syntax:\n"                                                          \
	"<device> <property> <channel> <value>"

#define CODEC_APPLY_PROP_HELP                                                                      \
	"Apply any cached properties. Syntax:\n"                                                   \
	"<device>"

static const char *const codec_property_name[] = {
	[AUDIO_PROPERTY_OUTPUT_VOLUME] = "volume",
	[AUDIO_PROPERTY_OUTPUT_MUTE] = "mute",
};

static const char *const codec_channel_name[] = {
	[AUDIO_CHANNEL_FRONT_LEFT] = "front_left",
	[AUDIO_CHANNEL_FRONT_RIGHT] = "front_right",
	[AUDIO_CHANNEL_LFE] = "lfe",
	[AUDIO_CHANNEL_FRONT_CENTER] = "front_center",
	[AUDIO_CHANNEL_REAR_LEFT] = "rear_left",
	[AUDIO_CHANNEL_REAR_RIGHT] = "rear_right",
	[AUDIO_CHANNEL_REAR_CENTER] = "rear_center",
	[AUDIO_CHANNEL_SIDE_LEFT] = "side_left",
	[AUDIO_CHANNEL_SIDE_RIGHT] = "side_right",
	[AUDIO_CHANNEL_ALL] = "all",
};

struct args_index {
	uint8_t device;
	uint8_t property;
	uint8_t channel;
	uint8_t value;
};

static const struct args_index args_indx = {
	.device = 1,
	.property = 2,
	.channel = 3,
	.value = 4,
};

static int parse_named_int(const char *name, const char *const keystack[], size_t count)
{
	char *endptr;
	int i;

	/* Attempt to parse name as a number first */
	i = strtoul(name, &endptr, 0);
	if (*endptr == '\0') {
		return i;
	}

	/* Name is not a number, look it up */
	for (i = 0; i < count; i++) {
		if (strcmp(name, keystack[i]) == 0) {
			return i;
		}
	}

	return -ENOTSUP;
}

static int cmd_start(const struct shell *sh, size_t argc, char *argv[])
{
	const struct device *dev;

	dev = device_get_binding(argv[args_indx.device]);
	if (!dev) {
		shell_error(sh, "Audio Codec device not found");
		return -ENODEV;
	}
	audio_codec_start_output(dev);

	return 0;
}

static int cmd_stop(const struct shell *sh, size_t argc, char *argv[])
{
	const struct device *dev;

	dev = device_get_binding(argv[args_indx.device]);
	if (!dev) {
		shell_error(sh, "Audio Codec device not found");
		return -ENODEV;
	}
	audio_codec_stop_output(dev);

	return 0;
}

static int cmd_set_prop(const struct shell *sh, size_t argc, char *argv[])
{
	const struct device *dev;
	int property;
	int channel;
	long value;
	char *endptr;
	audio_property_value_t property_value;

	dev = device_get_binding(argv[args_indx.device]);
	if (!dev) {
		shell_error(sh, "Audio Codec device not found");
		return -ENODEV;
	}

	property = parse_named_int(argv[args_indx.property], codec_property_name,
				   ARRAY_SIZE(codec_property_name));
	if (property < 0) {
		shell_error(sh, "Property '%s' unknown", argv[args_indx.property]);
		return -EINVAL;
	}

	channel = parse_named_int(argv[args_indx.channel], codec_channel_name,
				  ARRAY_SIZE(codec_channel_name));
	if (channel < 0) {
		shell_error(sh, "Channel '%s' unknown", argv[args_indx.channel]);
		return -EINVAL;
	}

	value = strtol(argv[args_indx.value], &endptr, 0);
	if (*endptr != '\0') {
		return -EINVAL;
	}
	if (value > INT32_MAX || value < INT32_MIN) {
		return -EINVAL;
	}
	switch (property) {
	case AUDIO_PROPERTY_OUTPUT_VOLUME:
		property_value.vol = value;
		break;
	case AUDIO_PROPERTY_OUTPUT_MUTE:
		property_value.mute = value;
		break;
	default:
		return -EINVAL;
	}

	return audio_codec_set_property(dev, property, channel, property_value);
}

static int cmd_apply_prop(const struct shell *sh, size_t argc, char *argv[])
{
	const struct device *dev;

	dev = device_get_binding(argv[args_indx.device]);
	if (!dev) {
		shell_error(sh, "Audio Codec device not found");
		return -ENODEV;
	}

	return audio_codec_apply_properties(dev);
}

/* Device name autocompletion support */
static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
	const struct device *dev = shell_device_lookup(idx, NULL);

	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);

/* clang-format off */
SHELL_STATIC_SUBCMD_SET_CREATE(sub_codec,
	SHELL_CMD_ARG(start, &dsub_device_name, CODEC_START_HELP, cmd_start,
			2, 0),
	SHELL_CMD_ARG(stop, &dsub_device_name, CODEC_STOP_HELP, cmd_stop,
			2, 0),
	SHELL_CMD_ARG(set_prop, &dsub_device_name, CODEC_SET_PROP_HELP, cmd_set_prop,
			5, 0),
	SHELL_CMD_ARG(apply_prop, &dsub_device_name, CODEC_APPLY_PROP_HELP, cmd_apply_prop,
			2, 0),
	SHELL_SUBCMD_SET_END
);
/* clang-format on */

SHELL_CMD_REGISTER(codec, &sub_codec, "Audio Codec commands", NULL);
