/*
 * Copyright (C) 2024 Birb Developers
 *
 * Birb is the legal property of its developers, whose names are too
 * numerous to list here. Please refer to the AUTHORS file distributed
 * with this source distribution
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
 */

#include <glib.h>

#include <birb.h>

/******************************************************************************
 * Filter Functions
 *****************************************************************************/
static gboolean
test_birb_custom_filter_match_all_func(GObject *item,
                                       G_GNUC_UNUSED gpointer data)
{
	birb_assert_type(item, G_TYPE_OBJECT);

	return TRUE;
}

static gboolean
test_birb_custom_filter_match_all_data_func(GObject *item, gpointer data) {
	g_assert_nonnull(data);
	birb_assert_type(item, G_TYPE_OBJECT);

	return TRUE;
}

/******************************************************************************
 * New Tests
 *****************************************************************************/
static void
test_birb_custom_filter_new_null(void) {
	BirbCustomFilter *filter = NULL;

	filter = birb_custom_filter_new(NULL, NULL, NULL);

	birb_assert_type(filter, BIRB_TYPE_CUSTOM_FILTER);

	g_assert_finalize_object(filter);
}

static void
test_birb_custom_filter_new_null_with_data_and_destroy(void) {
	BirbCustomFilter *filter = NULL;
	GObject *item = NULL;

	item = g_object_new(G_TYPE_OBJECT, NULL);

	filter = birb_custom_filter_new(NULL, g_object_ref(item), g_object_unref);

	birb_assert_type(filter, BIRB_TYPE_CUSTOM_FILTER);

	g_assert_finalize_object(filter);
	g_assert_finalize_object(item);
}

static void
test_birb_custom_filter_new_with_match_func(void) {
	BirbCustomFilter *filter = NULL;

	filter = birb_custom_filter_new(test_birb_custom_filter_match_all_func,
	                                NULL, NULL);

	birb_assert_type(filter, BIRB_TYPE_CUSTOM_FILTER);

	g_assert_finalize_object(filter);
}

static void
test_birb_custom_filter_new_with_match_func_and_data(void) {
	BirbCustomFilter *filter = NULL;
	guint data = 0;

	filter = birb_custom_filter_new(test_birb_custom_filter_match_all_data_func,
	                                &data, NULL);

	birb_assert_type(filter, BIRB_TYPE_CUSTOM_FILTER);

	g_assert_finalize_object(filter);
}

static void
test_birb_custom_filter_new_full(void) {
	BirbCustomFilter *filter = NULL;
	GObject *item = NULL;

	item = g_object_new(G_TYPE_OBJECT, NULL);

	filter = birb_custom_filter_new(test_birb_custom_filter_match_all_data_func,
	                                g_object_ref(item), g_object_unref);

	birb_assert_type(filter, BIRB_TYPE_CUSTOM_FILTER);

	g_assert_finalize_object(filter);
	g_assert_finalize_object(item);
}

/******************************************************************************
 * Matches tests
 *****************************************************************************/
static gboolean
test_birb_custom_filter_matches_func(GObject *item, gpointer data) {
	gboolean result = GPOINTER_TO_INT(data);

	birb_assert_type(item, G_TYPE_OBJECT);

	return result;
}

static void
test_birb_custom_filter_matches(gconstpointer data) {
	BirbCustomFilter *filter = NULL;
	GObject *item = NULL;
	gboolean result = GPOINTER_TO_INT(data);

	item = g_object_new(G_TYPE_OBJECT, NULL);

	filter = birb_custom_filter_new(test_birb_custom_filter_matches_func,
	                                (gpointer)data, NULL);

	g_assert_true(birb_filter_matches(BIRB_FILTER(filter), item) == result);

	g_assert_finalize_object(filter);
	g_assert_finalize_object(item);
}

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

	g_test_set_nonfatal_assertions();

	g_test_add_func("/custom-filter/new/null",
	                test_birb_custom_filter_new_null);
	g_test_add_func("/custom-filter/new/null-with-data-and-destroy",
	                test_birb_custom_filter_new_null_with_data_and_destroy);
	g_test_add_func("/custom-filter/new/with-match-func",
	                test_birb_custom_filter_new_with_match_func);
	g_test_add_func("/custom-filter/new/with-match-func-and-data",
	                test_birb_custom_filter_new_with_match_func_and_data);
	g_test_add_func("/custom-filter/new/full",
	                test_birb_custom_filter_new_full);

	g_test_add_data_func("/custom-filter/matches/true",
	                     GINT_TO_POINTER(TRUE),
	                     test_birb_custom_filter_matches);
	g_test_add_data_func("/custom-filter/matches/false",
	                     GINT_TO_POINTER(FALSE),
	                     test_birb_custom_filter_matches);

	return g_test_run();
}
