/*
 * GPIO chardev test helper
 *
 * Copyright (C) 2016 Bamvor Jian Zhang
 *
 * 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.
 */

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <libmount.h>
#include <err.h>
#include <dirent.h>
#include <linux/gpio.h>
#include "../../../gpio/gpio-utils.h"

#define CONSUMER	"gpio-selftest"
#define	GC_NUM		10
enum direction {
	OUT,
	IN
};

static int get_debugfs(char **path)
{
	struct libmnt_context *cxt;
	struct libmnt_table *tb;
	struct libmnt_iter *itr = NULL;
	struct libmnt_fs *fs;
	int found = 0, ret;

	cxt = mnt_new_context();
	if (!cxt)
		err(EXIT_FAILURE, "libmount context allocation failed");

	itr = mnt_new_iter(MNT_ITER_FORWARD);
	if (!itr)
		err(EXIT_FAILURE, "failed to initialize libmount iterator");

	if (mnt_context_get_mtab(cxt, &tb))
		err(EXIT_FAILURE, "failed to read mtab");

	while (mnt_table_next_fs(tb, itr, &fs) == 0) {
		const char *type = mnt_fs_get_fstype(fs);

		if (!strcmp(type, "debugfs")) {
			found = 1;
			break;
		}
	}
	if (found) {
		ret = asprintf(path, "%s/gpio", mnt_fs_get_target(fs));
		if (ret < 0)
			err(EXIT_FAILURE, "failed to format string");
	}

	mnt_free_iter(itr);
	mnt_free_context(cxt);

	if (!found)
		return -1;

	return 0;
}

static int gpio_debugfs_get(const char *consumer, int *dir, int *value)
{
	char *debugfs;
	FILE *f;
	char *line = NULL;
	size_t len = 0;
	char *cur;
	int found = 0;

	if (get_debugfs(&debugfs) != 0)
		err(EXIT_FAILURE, "debugfs is not mounted");

	f = fopen(debugfs, "r");
	if (!f)
		err(EXIT_FAILURE, "read from gpio debugfs failed");

	/*
	 * gpio-2   (                    |gpio-selftest               ) in  lo
	 */
	while (getline(&line, &len, f) != -1) {
		cur = strstr(line, consumer);
		if (cur == NULL)
			continue;

		cur = strchr(line, ')');
		if (!cur)
			continue;

		cur += 2;
		if (!strncmp(cur, "out", 3)) {
			*dir = OUT;
			cur += 4;
		} else if (!strncmp(cur, "in", 2)) {
			*dir = IN;
			cur += 4;
		}

		if (!strncmp(cur, "hi", 2))
			*value = 1;
		else if (!strncmp(cur, "lo", 2))
			*value = 0;

		found = 1;
		break;
	}
	free(debugfs);
	fclose(f);
	free(line);

	if (!found)
		return -1;

	return 0;
}

static struct gpiochip_info *list_gpiochip(const char *gpiochip_name, int *ret)
{
	struct gpiochip_info *cinfo;
	struct gpiochip_info *current;
	const struct dirent *ent;
	DIR *dp;
	char *chrdev_name;
	int fd;
	int i = 0;

	cinfo = calloc(sizeof(struct gpiochip_info) * 4, GC_NUM + 1);
	if (!cinfo)
		err(EXIT_FAILURE, "gpiochip_info allocation failed");

	current = cinfo;
	dp = opendir("/dev");
	if (!dp) {
		*ret = -errno;
		goto error_out;
	} else {
		*ret = 0;
	}

	while (ent = readdir(dp), ent) {
		if (check_prefix(ent->d_name, "gpiochip")) {
			*ret = asprintf(&chrdev_name, "/dev/%s", ent->d_name);
			if (*ret < 0)
				goto error_out;

			fd = open(chrdev_name, 0);
			if (fd == -1) {
				*ret = -errno;
				fprintf(stderr, "Failed to open %s\n",
					chrdev_name);
				goto error_close_dir;
			}
			*ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, current);
			if (*ret == -1) {
				perror("Failed to issue CHIPINFO IOCTL\n");
				goto error_close_dir;
			}
			close(fd);
			if (strcmp(current->label, gpiochip_name) == 0
			    || check_prefix(current->label, gpiochip_name)) {
				*ret = 0;
				current++;
				i++;
			}
		}
	}

	if ((!*ret && i == 0) || *ret < 0) {
		free(cinfo);
		cinfo = NULL;
	}
	if (!*ret && i > 0) {
		cinfo = realloc(cinfo, sizeof(struct gpiochip_info) * 4 * i);
		*ret = i;
	}

error_close_dir:
	closedir(dp);
error_out:
	if (*ret < 0)
		err(EXIT_FAILURE, "list gpiochip failed: %s", strerror(*ret));

	return cinfo;
}

int gpio_pin_test(struct gpiochip_info *cinfo, int line, int flag, int value)
{
	struct gpiohandle_data data;
	unsigned int lines[] = {line};
	int fd;
	int debugfs_dir = IN;
	int debugfs_value = 0;
	int ret;

	data.values[0] = value;
	ret = gpiotools_request_linehandle(cinfo->name, lines, 1, flag, &data,
					   CONSUMER);
	if (ret < 0)
		goto fail_out;
	else
		fd = ret;

	ret = gpio_debugfs_get(CONSUMER, &debugfs_dir, &debugfs_value);
	if (ret) {
		ret = -EINVAL;
		goto fail_out;
	}
	if (flag & GPIOHANDLE_REQUEST_INPUT) {
		if (debugfs_dir != IN) {
			errno = -EINVAL;
			ret = -errno;
		}
	} else if (flag & GPIOHANDLE_REQUEST_OUTPUT) {
		if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW)
			debugfs_value = !debugfs_value;

		if (!(debugfs_dir == OUT && value == debugfs_value)) {
			errno = -EINVAL;
			ret = -errno;
		}
	}
	gpiotools_release_linehandle(fd);

fail_out:
	if (ret)
		err(EXIT_FAILURE, "gpio<%s> line<%d> test flag<0x%x> value<%d>",
		    cinfo->name, line, flag, value);

	return ret;
}

void gpio_pin_tests(struct gpiochip_info *cinfo, unsigned int line)
{
	printf("line<%d>", line);
	gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 0);
	printf(".");
	gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 1);
	printf(".");
	gpio_pin_test(cinfo, line,
		      GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
		      0);
	printf(".");
	gpio_pin_test(cinfo, line,
		      GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
		      1);
	printf(".");
	gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_INPUT, 0);
	printf(".");
}

/*
 * ./gpio-mockup-chardev gpio_chip_name_prefix is_valid_gpio_chip
 * Return 0 if successful or exit with EXIT_FAILURE if test failed.
 * gpio_chip_name_prefix: The prefix of gpiochip you want to test. E.g.
 *			  gpio-mockup
 * is_valid_gpio_chip:	  Whether the gpio_chip is valid. 1 means valid,
 *			  0 means invalid which could not be found by
 *			  list_gpiochip.
 */
int main(int argc, char *argv[])
{
	char *prefix;
	int valid;
	struct gpiochip_info *cinfo;
	struct gpiochip_info *current;
	int i;
	int ret;

	if (argc < 3) {
		printf("Usage: %s prefix is_valid", argv[0]);
		exit(EXIT_FAILURE);
	}

	prefix = argv[1];
	valid = strcmp(argv[2], "true") == 0 ? 1 : 0;

	printf("Test gpiochip %s: ", prefix);
	cinfo = list_gpiochip(prefix, &ret);
	if (!cinfo) {
		if (!valid && ret == 0) {
			printf("Invalid test successful\n");
			ret = 0;
			goto out;
		} else {
			ret = -EINVAL;
			goto out;
		}
	} else if (cinfo && !valid) {
		ret = -EINVAL;
		goto out;
	}
	current = cinfo;
	for (i = 0; i < ret; i++) {
		gpio_pin_tests(current, 0);
		gpio_pin_tests(current, current->lines - 1);
		gpio_pin_tests(current, random() % current->lines);
		current++;
	}
	ret = 0;
	printf("successful\n");

out:
	if (ret)
		fprintf(stderr, "gpio<%s> test failed\n", prefix);

	if (cinfo)
		free(cinfo);

	if (ret)
		exit(EXIT_FAILURE);

	return ret;
}
