// SPDX-License-Identifier: GPL-2.0
//
// kselftest configuration helpers for the hw specific configuration
//
// Original author: Jaroslav Kysela <perex@perex.cz>
// Copyright (c) 2022 Red Hat Inc.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <assert.h>
#include <dirent.h>
#include <regex.h>
#include <sys/stat.h>

#include "../kselftest.h"
#include "alsa-local.h"

#define SYSFS_ROOT "/sys"

struct card_cfg_data *conf_cards;

static const char *alsa_config =
"ctl.hw {\n"
"	@args [ CARD ]\n"
"	@args.CARD.type string\n"
"	type hw\n"
"	card $CARD\n"
"}\n"
"pcm.hw {\n"
"	@args [ CARD DEV SUBDEV ]\n"
"	@args.CARD.type string\n"
"	@args.DEV.type integer\n"
"	@args.SUBDEV.type integer\n"
"	type hw\n"
"	card $CARD\n"
"	device $DEV\n"
"	subdevice $SUBDEV\n"
"}\n"
;

#ifdef SND_LIB_VER
#if SND_LIB_VERSION >= SND_LIB_VER(1, 2, 6)
#define LIB_HAS_LOAD_STRING
#endif
#endif

#ifndef LIB_HAS_LOAD_STRING
static int snd_config_load_string(snd_config_t **config, const char *s,
				  size_t size)
{
	snd_input_t *input;
	snd_config_t *dst;
	int err;

	assert(config && s);
	if (size == 0)
		size = strlen(s);
	err = snd_input_buffer_open(&input, s, size);
	if (err < 0)
		return err;
	err = snd_config_top(&dst);
	if (err < 0) {
		snd_input_close(input);
		return err;
	}
	err = snd_config_load(dst, input);
	snd_input_close(input);
	if (err < 0) {
		snd_config_delete(dst);
		return err;
	}
	*config = dst;
	return 0;
}
#endif

snd_config_t *get_alsalib_config(void)
{
	snd_config_t *config;
	int err;

	err = snd_config_load_string(&config, alsa_config, strlen(alsa_config));
	if (err < 0) {
		ksft_print_msg("Unable to parse custom alsa-lib configuration: %s\n",
			       snd_strerror(err));
		ksft_exit_fail();
	}
	return config;
}

static struct card_cfg_data *conf_data_by_card(int card, bool msg)
{
	struct card_cfg_data *conf;

	for (conf = conf_cards; conf; conf = conf->next) {
		if (conf->card == card) {
			if (msg)
				ksft_print_msg("using hw card config %s for card %d\n",
					       conf->filename, card);
			return conf;
		}
	}
	return NULL;
}

static void dump_config_tree(snd_config_t *top)
{
	snd_output_t *out;
	int err;

	err = snd_output_stdio_attach(&out, stdout, 0);
	if (err < 0)
		ksft_exit_fail_msg("stdout attach\n");
	if (snd_config_save(top, out))
		ksft_exit_fail_msg("config save\n");
	snd_output_close(out);
}

snd_config_t *conf_load_from_file(const char *filename)
{
	snd_config_t *dst;
	snd_input_t *input;
	int err;

	err = snd_input_stdio_open(&input, filename, "r");
	if (err < 0)
		ksft_exit_fail_msg("Unable to parse filename %s\n", filename);
	err = snd_config_top(&dst);
	if (err < 0)
		ksft_exit_fail_msg("Out of memory\n");
	err = snd_config_load(dst, input);
	snd_input_close(input);
	if (err < 0)
		ksft_exit_fail_msg("Unable to parse filename %s\n", filename);
	return dst;
}

static char *sysfs_get(const char *sysfs_root, const char *id)
{
	char path[PATH_MAX], link[PATH_MAX + 1];
	struct stat sb;
	ssize_t len;
	char *e;
	int fd;

	if (id[0] == '/')
		id++;
	snprintf(path, sizeof(path), "%s/%s", sysfs_root, id);
	if (lstat(path, &sb) != 0)
		return NULL;
	if (S_ISLNK(sb.st_mode)) {
		len = readlink(path, link, sizeof(link) - 1);
		if (len <= 0) {
			ksft_exit_fail_msg("sysfs: cannot read link '%s': %s\n",
					   path, strerror(errno));
			return NULL;
		}
		link[len] = '\0';
		e = strrchr(link, '/');
		if (e)
			return strdup(e + 1);
		return NULL;
	}
	if (S_ISDIR(sb.st_mode))
		return NULL;
	if ((sb.st_mode & S_IRUSR) == 0)
		return NULL;

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		if (errno == ENOENT)
			return NULL;
		ksft_exit_fail_msg("sysfs: open failed for '%s': %s\n",
				   path, strerror(errno));
	}
	len = read(fd, path, sizeof(path)-1);
	close(fd);
	if (len < 0)
		ksft_exit_fail_msg("sysfs: unable to read value '%s': %s\n",
				   path, strerror(errno));
	while (len > 0 && path[len-1] == '\n')
		len--;
	path[len] = '\0';
	e = strdup(path);
	if (e == NULL)
		ksft_exit_fail_msg("Out of memory\n");
	return e;
}

static bool sysfs_match(const char *sysfs_root, snd_config_t *config)
{
	snd_config_t *node, *path_config, *regex_config;
	snd_config_iterator_t i, next;
	const char *path_string, *regex_string, *v;
	regex_t re;
	regmatch_t match[1];
	int iter = 0, ret;

	snd_config_for_each(i, next, config) {
		node = snd_config_iterator_entry(i);
		if (snd_config_search(node, "path", &path_config))
			ksft_exit_fail_msg("Missing path field in the sysfs block\n");
		if (snd_config_search(node, "regex", &regex_config))
			ksft_exit_fail_msg("Missing regex field in the sysfs block\n");
		if (snd_config_get_string(path_config, &path_string))
			ksft_exit_fail_msg("Path field in the sysfs block is not a string\n");
		if (snd_config_get_string(regex_config, &regex_string))
			ksft_exit_fail_msg("Regex field in the sysfs block is not a string\n");
		iter++;
		v = sysfs_get(sysfs_root, path_string);
		if (!v)
			return false;
		if (regcomp(&re, regex_string, REG_EXTENDED))
			ksft_exit_fail_msg("Wrong regex '%s'\n", regex_string);
		ret = regexec(&re, v, 1, match, 0);
		regfree(&re);
		if (ret)
			return false;
	}
	return iter > 0;
}

static void assign_card_config(int card, const char *sysfs_card_root)
{
	struct card_cfg_data *data;
	snd_config_t *sysfs_card_config;

	for (data = conf_cards; data; data = data->next) {
		snd_config_search(data->config, "sysfs", &sysfs_card_config);
		if (!sysfs_match(sysfs_card_root, sysfs_card_config))
			continue;

		data->card = card;
		break;
	}
}

static void assign_card_configs(void)
{
	char fn[128];
	int card;

	for (card = 0; card < 32; card++) {
		snprintf(fn, sizeof(fn), "%s/class/sound/card%d", SYSFS_ROOT, card);
		if (access(fn, R_OK) == 0)
			assign_card_config(card, fn);
	}
}

static int filename_filter(const struct dirent *dirent)
{
	size_t flen;

	if (dirent == NULL)
		return 0;
	if (dirent->d_type == DT_DIR)
		return 0;
	flen = strlen(dirent->d_name);
	if (flen <= 5)
		return 0;
	if (strncmp(&dirent->d_name[flen-5], ".conf", 5) == 0)
		return 1;
	return 0;
}

static bool match_config(const char *filename)
{
	struct card_cfg_data *data;
	snd_config_t *config, *sysfs_config, *card_config, *sysfs_card_config, *node;
	snd_config_iterator_t i, next;

	config = conf_load_from_file(filename);
	if (snd_config_search(config, "sysfs", &sysfs_config) ||
	    snd_config_get_type(sysfs_config) != SND_CONFIG_TYPE_COMPOUND)
		ksft_exit_fail_msg("Missing global sysfs block in filename %s\n", filename);
	if (snd_config_search(config, "card", &card_config) ||
	    snd_config_get_type(card_config) != SND_CONFIG_TYPE_COMPOUND)
		ksft_exit_fail_msg("Missing global card block in filename %s\n", filename);
	if (!sysfs_match(SYSFS_ROOT, sysfs_config))
		return false;
	snd_config_for_each(i, next, card_config) {
		node = snd_config_iterator_entry(i);
		if (snd_config_search(node, "sysfs", &sysfs_card_config) ||
		    snd_config_get_type(sysfs_card_config) != SND_CONFIG_TYPE_COMPOUND)
			ksft_exit_fail_msg("Missing card sysfs block in filename %s\n", filename);

		data = malloc(sizeof(*data));
		if (!data)
			ksft_exit_fail_msg("Out of memory\n");
		data->filename = filename;
		data->config = node;
		data->card = -1;
		if (snd_config_get_id(node, &data->config_id))
			ksft_exit_fail_msg("snd_config_get_id failed for card\n");
		data->next = conf_cards;
		conf_cards = data;
	}
	return true;
}

void conf_load(void)
{
	const char *fn = "conf.d";
	struct dirent **namelist;
	int n, j;

	n = scandir(fn, &namelist, filename_filter, alphasort);
	if (n < 0)
		ksft_exit_fail_msg("scandir: %s\n", strerror(errno));
	for (j = 0; j < n; j++) {
		size_t sl = strlen(fn) + strlen(namelist[j]->d_name) + 2;
		char *filename = malloc(sl);
		if (filename == NULL)
			ksft_exit_fail_msg("Out of memory\n");
		sprintf(filename, "%s/%s", fn, namelist[j]->d_name);
		if (match_config(filename))
			filename = NULL;
		free(filename);
		free(namelist[j]);
	}
	free(namelist);

	assign_card_configs();
}

void conf_free(void)
{
	struct card_cfg_data *conf;

	while (conf_cards) {
		conf = conf_cards;
		conf_cards = conf->next;
		snd_config_delete(conf->config);
	}
}

snd_config_t *conf_by_card(int card)
{
	struct card_cfg_data *conf;

	conf = conf_data_by_card(card, true);
	if (conf)
		return conf->config;
	return NULL;
}

static int conf_get_by_keys(snd_config_t *root, const char *key1,
			    const char *key2, snd_config_t **result)
{
	int ret;

	if (key1) {
		ret = snd_config_search(root, key1, &root);
		if (ret != -ENOENT && ret < 0)
			return ret;
	}
	if (key2)
		ret = snd_config_search(root, key2, &root);
	if (ret >= 0)
		*result = root;
	return ret;
}

snd_config_t *conf_get_subtree(snd_config_t *root, const char *key1, const char *key2)
{
	int ret;

	if (!root)
		return NULL;
	ret = conf_get_by_keys(root, key1, key2, &root);
	if (ret == -ENOENT)
		return NULL;
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	return root;
}

int conf_get_count(snd_config_t *root, const char *key1, const char *key2)
{
	snd_config_t *cfg;
	snd_config_iterator_t i, next;
	int count, ret;

	if (!root)
		return -1;
	ret = conf_get_by_keys(root, key1, key2, &cfg);
	if (ret == -ENOENT)
		return -1;
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND)
		ksft_exit_fail_msg("key '%s'.'%s' is not a compound\n", key1, key2);
	count = 0;
	snd_config_for_each(i, next, cfg)
		count++;
	return count;
}

const char *conf_get_string(snd_config_t *root, const char *key1, const char *key2, const char *def)
{
	snd_config_t *cfg;
	const char *s;
	int ret;

	if (!root)
		return def;
	ret = conf_get_by_keys(root, key1, key2, &cfg);
	if (ret == -ENOENT)
		return def;
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	if (snd_config_get_string(cfg, &s))
		ksft_exit_fail_msg("key '%s'.'%s' is not a string\n", key1, key2);
	return s;
}

long conf_get_long(snd_config_t *root, const char *key1, const char *key2, long def)
{
	snd_config_t *cfg;
	long l;
	int ret;

	if (!root)
		return def;
	ret = conf_get_by_keys(root, key1, key2, &cfg);
	if (ret == -ENOENT)
		return def;
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	if (snd_config_get_integer(cfg, &l))
		ksft_exit_fail_msg("key '%s'.'%s' is not an integer\n", key1, key2);
	return l;
}

int conf_get_bool(snd_config_t *root, const char *key1, const char *key2, int def)
{
	snd_config_t *cfg;
	int ret;

	if (!root)
		return def;
	ret = conf_get_by_keys(root, key1, key2, &cfg);
	if (ret == -ENOENT)
		return def;
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	ret = snd_config_get_bool(cfg);
	if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' is not an bool\n", key1, key2);
	return !!ret;
}

void conf_get_string_array(snd_config_t *root, const char *key1, const char *key2,
			   const char **array, int array_size, const char *def)
{
	snd_config_t *cfg;
	char buf[16];
	int ret, index;

	ret = conf_get_by_keys(root, key1, key2, &cfg);
	if (ret == -ENOENT)
		cfg = NULL;
	else if (ret < 0)
		ksft_exit_fail_msg("key '%s'.'%s' search error: %s\n", key1, key2, snd_strerror(ret));
	for (index = 0; index < array_size; index++) {
		if (cfg == NULL) {
			array[index] = def;
		} else {
			sprintf(buf, "%i", index);
			array[index] = conf_get_string(cfg, buf, NULL, def);
		}
	}
}
