/*
 * Industrial I/O utilities - lsiio.c
 *
 * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */

#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include "iio_utils.h"

static enum verbosity {
	VERBLEVEL_DEFAULT,	/* 0 gives lspci behaviour */
	VERBLEVEL_SENSORS,	/* 1 lists sensors */
} verblevel = VERBLEVEL_DEFAULT;

const char *type_device = "iio:device";
const char *type_trigger = "trigger";

static inline int check_prefix(const char *str, const char *prefix)
{
	return strlen(str) > strlen(prefix) &&
	       strncmp(str, prefix, strlen(prefix)) == 0;
}

static inline int check_postfix(const char *str, const char *postfix)
{
	return strlen(str) > strlen(postfix) &&
	       strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
}

static int dump_channels(const char *dev_dir_name)
{
	DIR *dp;
	const struct dirent *ent;

	dp = opendir(dev_dir_name);
	if (!dp)
		return -errno;

	while (ent = readdir(dp), ent)
		if (check_prefix(ent->d_name, "in_") &&
		   (check_postfix(ent->d_name, "_raw") ||
		    check_postfix(ent->d_name, "_input")))
			printf("   %-10s\n", ent->d_name);

	return (closedir(dp) == -1) ? -errno : 0;
}

static int dump_one_device(const char *dev_dir_name)
{
	char name[IIO_MAX_NAME_LENGTH];
	int dev_idx;
	int ret;

	ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
		     &dev_idx);
	if (ret != 1)
		return -EINVAL;

	ret = read_sysfs_string("name", dev_dir_name, name);
	if (ret < 0)
		return ret;

	printf("Device %03d: %s\n", dev_idx, name);

	if (verblevel >= VERBLEVEL_SENSORS)
		return dump_channels(dev_dir_name);

	return 0;
}

static int dump_one_trigger(const char *dev_dir_name)
{
	char name[IIO_MAX_NAME_LENGTH];
	int dev_idx;
	int ret;

	ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
		     "%i", &dev_idx);
	if (ret != 1)
		return -EINVAL;

	ret = read_sysfs_string("name", dev_dir_name, name);
	if (ret < 0)
		return ret;

	printf("Trigger %03d: %s\n", dev_idx, name);

	return 0;
}

static int dump_devices(void)
{
	const struct dirent *ent;
	int ret;
	DIR *dp;

	dp = opendir(iio_dir);
	if (!dp) {
		fprintf(stderr, "No industrial I/O devices available\n");
		return -ENODEV;
	}

	while (ent = readdir(dp), ent) {
		if (check_prefix(ent->d_name, type_device)) {
			char *dev_dir_name;

			if (asprintf(&dev_dir_name, "%s%s", iio_dir,
				     ent->d_name) < 0) {
				ret = -ENOMEM;
				goto error_close_dir;
			}

			ret = dump_one_device(dev_dir_name);
			if (ret) {
				free(dev_dir_name);
				goto error_close_dir;
			}

			free(dev_dir_name);
			if (verblevel >= VERBLEVEL_SENSORS)
				printf("\n");
		}
	}
	rewinddir(dp);
	while (ent = readdir(dp), ent) {
		if (check_prefix(ent->d_name, type_trigger)) {
			char *dev_dir_name;

			if (asprintf(&dev_dir_name, "%s%s", iio_dir,
				     ent->d_name) < 0) {
				ret = -ENOMEM;
				goto error_close_dir;
			}

			ret = dump_one_trigger(dev_dir_name);
			if (ret) {
				free(dev_dir_name);
				goto error_close_dir;
			}

			free(dev_dir_name);
		}
	}

	return (closedir(dp) == -1) ? -errno : 0;

error_close_dir:
	if (closedir(dp) == -1)
		perror("dump_devices(): Failed to close directory");

	return ret;
}

int main(int argc, char **argv)
{
	int c, err = 0;

	while ((c = getopt(argc, argv, "v")) != EOF) {
		switch (c) {
		case 'v':
			verblevel++;
			break;

		case '?':
		default:
			err++;
			break;
		}
	}
	if (err || argc > optind) {
		fprintf(stderr, "Usage: lsiio [options]...\n"
			"List industrial I/O devices\n"
			"  -v  Increase verbosity (may be given multiple times)\n");
		exit(1);
	}

	return dump_devices();
}
