/*
 * libiio - Library for interfacing industrial I/O (IIO) devices
 *
 * Copyright (C) 2014 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * */

#include <errno.h>
#include <getopt.h>
#include <iio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MY_NAME "iio_info"

#ifdef _WIN32
#define snprintf sprintf_s
#endif

enum backend {
	LOCAL,
	XML,
	NETWORK,
	AUTO,
};

static const struct option options[] = {
	  {"help", no_argument, 0, 'h'},
	  {"xml", required_argument, 0, 'x'},
	  {"network", required_argument, 0, 'n'},
	  {"uri", required_argument, 0, 'u'},
	  {"scan", no_argument, 0, 's'},
	  {"auto", no_argument, 0, 'a'},
	  {0, 0, 0, 0},
};

static const char *options_descriptions[] = {
	"Show this help and quit.",
	"Use the XML backend with the provided XML file.",
	"Use the network backend with the provided hostname.",
	"Use the context at the provided URI.",
	"Scan for available backends.",
	"Scan for available contexts and if only one is available use it.",
};

static void usage(void)
{
	unsigned int i;

	printf("Usage:\n\t" MY_NAME " [-x <xml_file>]\n\t"
			MY_NAME " [-n <hostname>]\n\t"
			MY_NAME " [-u <uri>]\n\nOptions:\n");
	for (i = 0; options[i].name; i++)
		printf("\t-%c, --%s\n\t\t\t%s\n",
					options[i].val, options[i].name,
					options_descriptions[i]);
}

static void scan(void)
{
	struct iio_scan_context *ctx;
	struct iio_context_info **info;
	unsigned int i;
	ssize_t ret;

	ctx = iio_create_scan_context(NULL, 0);
	if (!ctx) {
		fprintf(stderr, "Unable to create scan context\n");
		return;
	}

	ret = iio_scan_context_get_info_list(ctx, &info);
	if (ret < 0) {
		fprintf(stderr, "Unable to scan: %li\n", (long) ret);
		goto err_free_ctx;
	}

	if (ret == 0) {
		printf("No contexts found.\n");
		goto err_free_info_list;
	}

	printf("Available contexts:\n");

	for (i = 0; i < (size_t) ret; i++) {
		printf("\t%d: %s [%s]\n", i,
			iio_context_info_get_description(info[i]),
			iio_context_info_get_uri(info[i]));
	}

err_free_info_list:
	iio_context_info_list_free(info);
err_free_ctx:
	iio_scan_context_destroy(ctx);
}

static struct iio_context * autodetect_context(void)
{
	struct iio_scan_context *scan_ctx;
	struct iio_context_info **info;
	struct iio_context *ctx = NULL;
	unsigned int i;
	ssize_t ret;

	scan_ctx = iio_create_scan_context(NULL, 0);
	if (!scan_ctx) {
		fprintf(stderr, "Unable to create scan context\n");
		return NULL;
	}

	ret = iio_scan_context_get_info_list(scan_ctx, &info);
	if (ret < 0) {
		char err_str[1024];
		iio_strerror(-ret, err_str, sizeof(err_str));
		fprintf(stderr, "Scanning for IIO contexts failed: %s\n", err_str);
		goto err_free_ctx;
	}

	if (ret == 0) {
		printf("No IIO context found.\n");
		goto err_free_info_list;
	}

	if (ret == 1) {
		printf("Using auto-detected IIO context at URI \"%s\"\n",
				iio_context_info_get_uri(info[0]));
		ctx = iio_create_context_from_uri(iio_context_info_get_uri(info[0]));
	} else {
		fprintf(stderr, "Multiple contexts found. Please select one using --uri:\n");

		for (i = 0; i < (size_t) ret; i++) {
			fprintf(stderr, "\t%d: %s [%s]\n", i,
				iio_context_info_get_description(info[i]),
				iio_context_info_get_uri(info[i]));
		}
	}

err_free_info_list:
	iio_context_info_list_free(info);
err_free_ctx:
	iio_scan_context_destroy(scan_ctx);

	return ctx;
}

static int dev_is_buffer_capable(const struct iio_device *dev)
{
	unsigned int i;

	for (i = 0; i < iio_device_get_channels_count(dev); i++) {
		struct iio_channel *chn = iio_device_get_channel(dev, i);

		if (iio_channel_is_scan_element(chn))
			return true;
	}

	return false;
}

int main(int argc, char **argv)
{
	struct iio_context *ctx;
	int c, option_index = 0;
	const char *arg_uri = NULL;
	const char *arg_ip = NULL;
	const char *arg_xml = NULL;
	enum backend backend = LOCAL;
	bool do_scan = false, detect_context = false;
	unsigned int i, major, minor;
	char git_tag[8];
	int ret;

	while ((c = getopt_long(argc, argv, "+hn:x:u:sa",
					options, &option_index)) != -1) {
		switch (c) {
		case 'h':
			usage();
			return EXIT_SUCCESS;
		case 'n':
			if (backend != LOCAL) {
				fprintf(stderr, "-x, -n and -u are mutually exclusive\n");
				return EXIT_FAILURE;
			}
			backend = NETWORK;
			arg_ip = optarg;
			break;
		case 'x':
			if (backend != LOCAL) {
				fprintf(stderr, "-x, -n and -u are mutually exclusive\n");
				return EXIT_FAILURE;
			}
			backend = XML;
			arg_xml = optarg;
			break;
		case 's':
			do_scan = true;
			break;
		case 'u':
			if (backend != LOCAL) {
				fprintf(stderr, "-x, -n and -u are mutually exclusive\n");
				return EXIT_FAILURE;
			}
			backend = AUTO;
			arg_uri = optarg;
			break;
		case 'a':
			detect_context = true;
			break;
		case '?':
			return EXIT_FAILURE;
		}
	}

	if (optind != argc) {
		fprintf(stderr, "Incorrect number of arguments.\n\n");
		usage();
		return EXIT_FAILURE;
	}

	iio_library_get_version(&major, &minor, git_tag);
	printf("Library version: %u.%u (git tag: %s)\n", major, minor, git_tag);

	printf("Compiled with backends:");
	for (i = 0; i < iio_get_backends_count(); i++)
		printf(" %s", iio_get_backend(i));
	printf("\n");

	if (do_scan) {
		scan();
		return EXIT_SUCCESS;
	}

	if (detect_context)
		ctx = autodetect_context();
	else if (backend == XML)
		ctx = iio_create_xml_context(arg_xml);
	else if (backend == NETWORK)
		ctx = iio_create_network_context(arg_ip);
	else if (backend == AUTO)
		ctx = iio_create_context_from_uri(arg_uri);
	else
		ctx = iio_create_default_context();

	if (!ctx) {
		if (!detect_context) {
			char buf[1024];

			iio_strerror(errno, buf, sizeof(buf));
			fprintf(stderr, "Unable to create IIO context: %s\n",
					buf);
		}

		return EXIT_FAILURE;
	}

	printf("IIO context created with %s backend.\n",
			iio_context_get_name(ctx));

	ret = iio_context_get_version(ctx, &major, &minor, git_tag);
	if (!ret)
		printf("Backend version: %u.%u (git tag: %s)\n",
				major, minor, git_tag);
	else
		fprintf(stderr, "Unable to get backend version: %i\n", ret);

	printf("Backend description string: %s\n",
			iio_context_get_description(ctx));

	unsigned int nb_ctx_attrs = iio_context_get_attrs_count(ctx);
	if (nb_ctx_attrs > 0)
		printf("IIO context has %u attributes:\n", nb_ctx_attrs);

	for (i = 0; i < nb_ctx_attrs; i++) {
		const char *key, *value;

		iio_context_get_attr(ctx, i, &key, &value);
		printf("\t%s: %s\n", key, value);
	}

	unsigned int nb_devices = iio_context_get_devices_count(ctx);
	printf("IIO context has %u devices:\n", nb_devices);

	for (i = 0; i < nb_devices; i++) {
		const struct iio_device *dev = iio_context_get_device(ctx, i);
		const char *name = iio_device_get_name(dev);
		printf("\t%s:", iio_device_get_id(dev));
		if (name)
			printf(" %s", name);
		if (dev_is_buffer_capable(dev))
			printf(" (buffer capable)");
		printf("\n");

		unsigned int nb_channels = iio_device_get_channels_count(dev);
		printf("\t\t%u channels found:\n", nb_channels);

		unsigned int j;
		for (j = 0; j < nb_channels; j++) {
			struct iio_channel *ch = iio_device_get_channel(dev, j);
			const char *type_name;

			if (iio_channel_is_output(ch))
				type_name = "output";
			else
				type_name = "input";

			name = iio_channel_get_name(ch);
			printf("\t\t\t%s: %s (%s",
					iio_channel_get_id(ch),
					name ? name : "", type_name);

			if (iio_channel_is_scan_element(ch)) {
				const struct iio_data_format *format =
					iio_channel_get_data_format(ch);
				char sign = format->is_signed ? 's' : 'u';
				char repeat[12] = "";

				if (format->is_fully_defined)
					sign += 'A' - 'a';

				if (format->repeat > 1)
					snprintf(repeat, sizeof(repeat), "X%u",
						format->repeat);

				printf(", index: %lu, format: %ce:%c%u/%u%s>>%u)\n",
					iio_channel_get_index(ch),
					format->is_be ? 'b' : 'l',
					sign, format->bits,
					format->length, repeat,
					format->shift);
			} else {
				printf(")\n");
			}

			unsigned int nb_attrs = iio_channel_get_attrs_count(ch);
			if (!nb_attrs)
				continue;

			printf("\t\t\t%u channel-specific attributes found:\n",
					nb_attrs);

			unsigned int k;
			for (k = 0; k < nb_attrs; k++) {
				const char *attr = iio_channel_get_attr(ch, k);
				char buf[1024];
				ret = (int) iio_channel_attr_read(ch,
						attr, buf, sizeof(buf));

				printf("\t\t\t\tattr %2u: %s ", k, attr);

				if (ret > 0) {
					printf("value: %s\n", buf);
				} else {
					iio_strerror(-ret, buf, sizeof(buf));
					printf("ERROR: %s (%i)\n", buf, ret);
				}
			}
		}

		unsigned int nb_attrs = iio_device_get_attrs_count(dev);
		if (nb_attrs) {
			printf("\t\t%u device-specific attributes found:\n",
					nb_attrs);
			for (j = 0; j < nb_attrs; j++) {
				const char *attr = iio_device_get_attr(dev, j);
				char buf[1024];
				ret = (int) iio_device_attr_read(dev,
						attr, buf, sizeof(buf));

				printf("\t\t\t\tattr %2u: %s ",
						j, attr);

				if (ret > 0) {
					printf("value: %s\n", buf);
				} else {
					iio_strerror(-ret, buf, sizeof(buf));
					printf("ERROR: %s (%i)\n", buf, ret);
				}
			}
		}

		nb_attrs = iio_device_get_buffer_attrs_count(dev);
		if (nb_attrs) {
			printf("\t\t%u buffer-specific attributes found:\n",
					nb_attrs);
			for (j = 0; j < nb_attrs; j++) {
				const char *attr = iio_device_get_buffer_attr(dev, j);
				char buf[1024];
				ret = (int) iio_device_buffer_attr_read(dev,
						attr, buf, sizeof(buf));

				printf("\t\t\t\tattr %2u: %s ",
						j, attr);

				if (ret > 0) {
					printf("value: %s\n", buf);
				} else {
					iio_strerror(-ret, buf, sizeof(buf));
					printf("ERROR: %s (%i)\n", buf, ret);
				}
			}
		}

		nb_attrs = iio_device_get_debug_attrs_count(dev);
		if (nb_attrs) {
			printf("\t\t%u debug attributes found:\n", nb_attrs);
			for (j = 0; j < nb_attrs; j++) {
				const char *attr =
					iio_device_get_debug_attr(dev, j);
				char buf[1024];

				ret = (int) iio_device_debug_attr_read(dev,
						attr, buf, sizeof(buf));
				printf("\t\t\t\tdebug attr %2u: %s ",
						j, attr);
				if (ret > 0) {
					printf("value: %s\n", buf);
				} else {
					iio_strerror(-ret, buf, sizeof(buf));
					printf("ERROR: %s (%i)\n", buf, ret);
				}
			}
		}

		const struct iio_device *trig;
		ret = iio_device_get_trigger(dev, &trig);
		if (ret == 0) {
			if (trig == NULL) {
				printf("\t\tNo trigger assigned to device\n");
			} else {
				name = iio_device_get_name(trig);
				printf("\t\tCurrent trigger: %s(%s)\n",
						iio_device_get_id(trig),
						name ? name : "");
			}
		}
	}

	iio_context_destroy(ctx);
	return EXIT_SUCCESS;
}
