/*
 * Copyright (C) 2011-2014 Gary Kramlich <grim@reaperworld.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 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib.h>

#include <gplugin.h>
#include <gplugin-native.h>

/******************************************************************************
 * Tests
 *****************************************************************************/
static void
test_gplugin_plugin_info_new_full(void)
{
	GPluginPluginInfo *info = NULL;
	GStrv authors = NULL;
	GStrv dependencies = NULL;
	GStrv provides = NULL;
	char *category = NULL;
	char *description = NULL;
	char *discriminator = NULL;
	char *icon_name = NULL;
	char *id = NULL;
	char *license_id = NULL;
	char *license_text = NULL;
	char *license_url = NULL;
	char *name = NULL;
	char *summary = NULL;
	char *version = NULL;
	char *website = NULL;
	int priority = 0;
	guint abi_version = 0;
	gboolean internal = FALSE;
	gboolean auto_load = FALSE;
	const char *const r_provides[] = {"foo", NULL};
	const char *const r_authors[] = {"author", NULL};
	const char *const r_dependencies[] = {"dependency", NULL};

	/* clang-format off */
	info = gplugin_plugin_info_new(
		"gplugin-test/plugin-info-test",
		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
		"authors", r_authors,
		"auto-load", TRUE,
		"category", "category",
		"dependencies", r_dependencies,
		"description", "description",
		"icon-name", "icon-name",
		"internal", TRUE,
		"license-id", "license-id",
		"license-text", "license-text",
		"license-url", "license-url",
		"name", "name",
		"priority", 1000,
		"provides", r_provides,
		"summary", "summary",
		"version", "version",
		"website", "website",
		NULL);
	/* clang-format on */

	g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));

	/* clang-format off */
	g_object_get(
		info,
		"abi_version", &abi_version,
		"authors", &authors,
		"auto-load", &auto_load,
		"category", &category,
		"dependencies", &dependencies,
		"description", &description,
		"discriminator", &discriminator,
		"icon-name", &icon_name,
		"id", &id,
		"internal", &internal,
		"license-id", &license_id,
		"license-text", &license_text,
		"license-url", &license_url,
		"name", &name,
		"priority", &priority,
		"provides", &provides,
		"summary", &summary,
		"version", &version,
		"website", &website,
		NULL);
	/* clang-format on */

	g_assert_cmpuint(abi_version, ==, GPLUGIN_NATIVE_PLUGIN_ABI_VERSION);

	g_assert_cmpstrv(authors, r_authors);
	g_clear_pointer(&authors, g_strfreev);

	g_assert_true(auto_load);

	g_assert_cmpstr(category, ==, "category");
	g_clear_pointer(&category, g_free);

	g_assert_cmpstrv(dependencies, r_dependencies);
	g_clear_pointer(&dependencies, g_strfreev);

	g_assert_cmpstr(description, ==, "description");
	g_clear_pointer(&description, g_free);

	/* We can't guarantee the value of the discriminator, so we just check that
	 * it is not a NULL or an empty string.
	 */
	g_assert_nonnull(discriminator);
	g_assert_cmpstr(discriminator, !=, "");
	g_clear_pointer(&discriminator, g_free);

	g_assert_cmpstr(icon_name, ==, "icon-name");
	g_clear_pointer(&icon_name, g_free);

	g_assert_cmpstr(id, ==, "gplugin-test/plugin-info-test");
	g_clear_pointer(&id, g_free);

	g_assert_true(internal);

	g_assert_cmpstr(license_id, ==, "license-id");
	g_clear_pointer(&license_id, g_free);

	g_assert_cmpstr(license_text, ==, "license-text");
	g_clear_pointer(&license_text, g_free);

	g_assert_cmpstr(license_url, ==, "license-url");
	g_clear_pointer(&license_url, g_free);

	g_assert_cmpstr(name, ==, "name");
	g_clear_pointer(&name, g_free);

	g_assert_cmpint(priority, ==, 1000);

	g_assert_cmpstrv(provides, r_provides);
	g_clear_pointer(&provides, g_strfreev);

	g_assert_cmpstr(summary, ==, "summary");
	g_clear_pointer(&summary, g_free);

	g_assert_cmpstr(website, ==, "website");
	g_clear_pointer(&website, g_free);

	g_assert_cmpstr(version, ==, "version");
	g_clear_pointer(&version, g_free);

	g_assert_finalize_object(info);
}

static void
test_gplugin_plugin_info_new_empty(void)
{
	GPluginPluginInfo *info = NULL;
	char *id = NULL;
	guint32 abi_version = 0;

	info = gplugin_plugin_info_new("empty", 1, NULL);

	g_assert_true(GPLUGIN_IS_PLUGIN_INFO(info));

	/* clang-format off */
	g_object_get(
		info,
		"id", &id,
		"abi-version", &abi_version,
		NULL);
	/* clang-format on */

	g_assert_cmpstr(id, ==, "empty");
	g_clear_pointer(&id, g_free);

	g_assert_cmpuint(abi_version, ==, 1);

	g_assert_finalize_object(info);
}

static void
test_gplugin_plugin_info_authors_single(void)
{
	GPluginPluginInfo *info = NULL;
	const char *const authors[] = {"author", NULL};
	const char *const *g_authors = NULL;

	/* clang-format off */
	info = gplugin_plugin_info_new(
		"test/single-author",
		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
		"authors", authors,
		NULL);
	/* clang-format on */

	g_authors = gplugin_plugin_info_get_authors(info);

	g_assert_cmpstrv(g_authors, authors);

	g_assert_finalize_object(info);
}

static void
test_gplugin_plugin_info_authors_multiple(void)
{
	GPluginPluginInfo *info = NULL;
	const char *const authors[] = {"author1", "author2", NULL};
	const char *const *g_authors = NULL;

	/* clang-format off */
	info = gplugin_plugin_info_new(
		"test/single-author",
		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
		"authors", authors,
		NULL);
	/* clang-format on */

	g_authors = gplugin_plugin_info_get_authors(info);

	g_assert_cmpstrv(g_authors, authors);

	g_assert_finalize_object(info);
}

static void
test_gplugin_plugin_info_dependencies_single(void)
{
	GPluginPluginInfo *info = NULL;
	char *dependencies[] = {"dependency1", NULL};
	const char *const *g_dependencies = NULL;

	/* clang-format off */
	info = gplugin_plugin_info_new(
		"test/single-dependency",
		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
		"dependencies", dependencies,
		NULL);
	/* clang-format on */

	g_dependencies = gplugin_plugin_info_get_dependencies(info);

	g_assert_cmpstrv(g_dependencies, dependencies);

	g_assert_finalize_object(info);
}

static void
test_gplugin_plugin_info_dependencies_multiple(void)
{
	GPluginPluginInfo *info = NULL;
	char *dependencies[] = {"dependency1", "dependency2", NULL};
	const char *const *g_dependencies = NULL;

	/* clang-format off */
	info = gplugin_plugin_info_new(
		"test/single-dependency",
		GPLUGIN_NATIVE_PLUGIN_ABI_VERSION,
		"dependencies", dependencies,
		NULL);
	/* clang-format on */

	g_dependencies = gplugin_plugin_info_get_dependencies(info);

	g_assert_cmpstrv(g_dependencies, dependencies);

	g_assert_finalize_object(info);
}

/******************************************************************************
 * Main
 *****************************************************************************/
int
main(int argc, char **argv)
{
	g_test_init(&argc, &argv, NULL);

	g_test_add_func("/plugin-info/new/full", test_gplugin_plugin_info_new_full);
	g_test_add_func(
		"/plugin-info/new/empty",
		test_gplugin_plugin_info_new_empty);

	g_test_add_func(
		"/plugin-info/authors/single",
		test_gplugin_plugin_info_authors_single);
	g_test_add_func(
		"/plugin-info/authors/multiple",
		test_gplugin_plugin_info_authors_multiple);

	g_test_add_func(
		"/plugin-info/dependencies/single",
		test_gplugin_plugin_info_dependencies_single);
	g_test_add_func(
		"/plugin-info/dependencies/multiple",
		test_gplugin_plugin_info_dependencies_multiple);

	return g_test_run();
}
