/*
 * 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 == NULL)
		return -errno;
	while (ent = readdir(dp), ent != NULL)
		if (check_prefix(ent->d_name, "in_") &&
		    check_postfix(ent->d_name, "_raw")) {
			printf("   %-10s\n", ent->d_name);
		}

	return 0;
}

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

	sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device),
			"%i", &dev_idx);
	read_sysfs_string("name", dev_dir_name, name);
	printf("Device %03d: %s\n", dev_idx, name);

	if (verblevel >= VERBLEVEL_SENSORS) {
		int ret = dump_channels(dev_dir_name);
		if (ret)
			return ret;
	}
	return 0;
}

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

	sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
			"%i", &dev_idx);
	read_sysfs_string("name", dev_dir_name, name);
	printf("Trigger %03d: %s\n", dev_idx, name);
	return 0;
}

static void dump_devices(void)
{
	const struct dirent *ent;
	int number, numstrlen;

	FILE *nameFile;
	DIR *dp;
	char thisname[IIO_MAX_NAME_LENGTH];
	char *filename;

	dp = opendir(iio_dir);
	if (dp == NULL) {
		printf("No industrial I/O devices available\n");
		return;
	}

	while (ent = readdir(dp), ent != NULL) {
		if (check_prefix(ent->d_name, type_device)) {
			char *dev_dir_name;
			asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name);
			dump_one_device(dev_dir_name);
			free(dev_dir_name);
			if (verblevel >= VERBLEVEL_SENSORS)
				printf("\n");
		}
	}
	rewinddir(dp);
	while (ent = readdir(dp), ent != NULL) {
		if (check_prefix(ent->d_name, type_trigger)) {
			char *dev_dir_name;
			asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name);
			dump_one_trigger(dev_dir_name);
			free(dev_dir_name);
		}
	}
	closedir(dp);
}

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

	while ((c = getopt(argc, argv, "d:D: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, --verbose\n"
			"      Increase verbosity (may be given multiple times)\n"
			);
		exit(1);
	}

	dump_devices();

	return 0;
}
