// SPDX-License-Identifier: LGPL-2.1-or-later
/*
 * This file is part of libgpiod.
 *
 * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
 */

#include <errno.h>
#include <glib/gstdio.h>
#include <gpio-mockup.h>
#include <linux/version.h>
#include <stdio.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "gpiod-test.h"

#define MIN_KERNEL_MAJOR	5
#define MIN_KERNEL_MINOR	5
#define MIN_KERNEL_RELEASE	0
#define MIN_KERNEL_VERSION	KERNEL_VERSION(MIN_KERNEL_MAJOR, \
					       MIN_KERNEL_MINOR, \
					       MIN_KERNEL_RELEASE)

struct gpiod_test_event_thread {
	GThread *id;
	GMutex lock;
	GCond cond;
	gboolean should_stop;
	guint chip_index;
	guint line_offset;
	guint freq;
};

static struct {
	GList *tests;
	struct gpio_mockup *mockup;
} globals;

static void check_kernel(void)
{
	guint major, minor, release;
	struct utsname un;
	gint ret;

	g_debug("checking linux kernel version");

	ret = uname(&un);
	if (ret)
		g_error("unable to read the kernel release version: %s",
			g_strerror(errno));

	ret = sscanf(un.release, "%u.%u.%u", &major, &minor, &release);
	if (ret != 3)
		g_error("error reading kernel release version");

	if (KERNEL_VERSION(major, minor, release) < MIN_KERNEL_VERSION)
		g_error("linux kernel version must be at least v%u.%u.%u - got v%u.%u.%u",
			MIN_KERNEL_MAJOR, MIN_KERNEL_MINOR, MIN_KERNEL_RELEASE,
			major, minor, release);

	g_debug("kernel release is v%u.%u.%u - ok to run tests",
		major, minor, release);

	return;
}

static void test_func_wrapper(gconstpointer data)
{
	const _GpiodTestCase *test = data;
	gint ret, flags = 0;

	if (test->flags & GPIOD_TEST_FLAG_NAMED_LINES)
		flags |= GPIO_MOCKUP_FLAG_NAMED_LINES;

	ret = gpio_mockup_probe(globals.mockup, test->num_chips,
				test->chip_sizes, flags);
	if (ret)
		g_error("unable to probe gpio-mockup: %s", g_strerror(errno));

	test->func();

	ret = gpio_mockup_remove(globals.mockup);
	if (ret)
		g_error("unable to remove gpio_mockup: %s", g_strerror(errno));
}

static void unref_mockup(void)
{
	gpio_mockup_unref(globals.mockup);
}

static void add_test_from_list(gpointer element, gpointer data G_GNUC_UNUSED)
{
	_GpiodTestCase *test = element;

	g_test_add_data_func(test->path, test, test_func_wrapper);
}

int main(gint argc, gchar **argv)
{
	g_test_init(&argc, &argv, NULL);
	g_test_set_nonfatal_assertions();

	g_debug("running libgpiod test suite");
	g_debug("%u tests registered", g_list_length(globals.tests));

	/*
	 * Setup libgpiomockup first so that it runs its own kernel version
	 * check before we tell the user our local requirements are met as
	 * well.
	 */
	globals.mockup = gpio_mockup_new();
	if (!globals.mockup)
		g_error("unable to initialize gpio-mockup library: %s",
			g_strerror(errno));
	atexit(unref_mockup);

	check_kernel();

	g_list_foreach(globals.tests, add_test_from_list, NULL);
	g_list_free(globals.tests);

	return g_test_run();
}

void _gpiod_test_register(_GpiodTestCase *test)
{
	globals.tests = g_list_append(globals.tests, test);
}

const gchar *gpiod_test_chip_path(guint idx)
{
	const gchar *path;

	path = gpio_mockup_chip_path(globals.mockup, idx);
	if (!path)
		g_error("unable to retrieve the chip path: %s",
			g_strerror(errno));

	return path;
}

const gchar *gpiod_test_chip_name(guint idx)
{
	const gchar *name;

	name = gpio_mockup_chip_name(globals.mockup, idx);
	if (!name)
		g_error("unable to retrieve the chip name: %s",
			g_strerror(errno));

	return name;
}

gint gpiod_test_chip_num(unsigned int idx)
{
	gint num;

	num = gpio_mockup_chip_num(globals.mockup, idx);
	if (num < 0)
		g_error("unable to retrieve the chip number: %s",
			g_strerror(errno));

	return num;
}

gint gpiod_test_chip_get_value(guint chip_index, guint line_offset)
{
	gint ret;

	ret = gpio_mockup_get_value(globals.mockup, chip_index, line_offset);
	if (ret < 0)
		g_error("unable to read line value from gpio-mockup: %s",
			g_strerror(errno));

	return ret;
}

void gpiod_test_chip_set_pull(guint chip_index, guint line_offset, gint pull)
{
	gint ret;

	ret = gpio_mockup_set_pull(globals.mockup, chip_index,
				   line_offset, pull);
	if (ret)
		g_error("unable to set line pull in gpio-mockup: %s",
			g_strerror(errno));
}

static gpointer event_worker_func(gpointer data)
{
	GpiodTestEventThread *thread = data;
	gboolean signalled;
	gint64 end_time;
	gint i;

	for (i = 0;; i++) {
		g_mutex_lock(&thread->lock);
		if (thread->should_stop) {
			g_mutex_unlock(&thread->lock);
			break;
		}

		end_time = g_get_monotonic_time() + thread->freq * 1000;

		signalled = g_cond_wait_until(&thread->cond,
					      &thread->lock, end_time);
		if (!signalled)
			gpiod_test_chip_set_pull(thread->chip_index,
						 thread->line_offset, i % 2);

		g_mutex_unlock(&thread->lock);
	}

	return NULL;
}

GpiodTestEventThread *
gpiod_test_start_event_thread(guint chip_index, guint line_offset, guint freq)
{
	GpiodTestEventThread *thread = g_malloc0(sizeof(*thread));

	g_mutex_init(&thread->lock);
	g_cond_init(&thread->cond);

	thread->chip_index = chip_index;
	thread->line_offset = line_offset;
	thread->freq = freq;

	thread->id = g_thread_new("event-worker", event_worker_func, thread);

	return thread;
}

void gpiod_test_stop_event_thread(GpiodTestEventThread *thread)
{
	g_mutex_lock(&thread->lock);
	thread->should_stop = TRUE;
	g_cond_broadcast(&thread->cond);
	g_mutex_unlock(&thread->lock);

	(void)g_thread_join(thread->id);

	g_mutex_clear(&thread->lock);
	g_cond_clear(&thread->cond);
	g_free(thread);
}
