/*
 * Copyright (C) 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 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 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
 */

#include <birb.h>

/******************************************************************************
 * clear tests
 *****************************************************************************/
static void
test_birb_time_zone_clear_null(void) {
	GTimeZone *tz = NULL;

	birb_time_zone_clear(NULL);
	birb_time_zone_clear(&tz);

	g_assert_null(tz);
}

static void
test_birb_time_zone_clear_nonnull(void) {
	GTimeZone *tz = g_time_zone_new_utc();

	birb_time_zone_clear(&tz);

	g_assert_null(tz);
}

/******************************************************************************
 * compare tests
 *****************************************************************************/
static void
test_birb_time_zone_compare_null(void) {
	GTimeZone *tz = g_time_zone_new_utc();
	int result;

	result = birb_time_zone_compare(tz, NULL);
	g_assert_cmpint(result, ==, 1);

	result = birb_time_zone_compare(NULL, tz);
	g_assert_cmpint(result, ==, -1);

	result = birb_time_zone_compare(NULL, NULL);
	g_assert_cmpint(result, ==, 0);

	g_time_zone_unref(tz);
}

static void
test_birb_time_zone_compare_nonnull(void) {
	GTimeZone *cet = g_time_zone_new_identifier("+01:00");
	GTimeZone *utc1 = g_time_zone_new_identifier("00:00");
	GTimeZone *utc2 = g_time_zone_new_utc();
	int result;

	result = birb_time_zone_compare(utc1, cet);
	g_assert_cmpint(result, ==, -1);

	result = birb_time_zone_compare(cet, utc1);
	g_assert_cmpint(result, ==, 1);

	result = birb_time_zone_compare(utc1, utc2);
	g_assert_cmpint(result, ==, 0);

	g_time_zone_unref(utc1);
	g_time_zone_unref(utc2);
	g_time_zone_unref(cet);
}

/******************************************************************************
 * equal tests
 *****************************************************************************/
static void
test_birb_time_zone_equal_null(void) {
	GTimeZone *tz = g_time_zone_new_utc();

	g_assert_false(birb_time_zone_equal(tz, NULL));
	g_assert_false(birb_time_zone_equal(NULL, tz));
	g_assert_true(birb_time_zone_equal(NULL, NULL));

	g_time_zone_unref(tz);
}

static void
test_birb_time_zone_equal_nonnull(void) {
	GTimeZone *utc1 = g_time_zone_new_utc();
	GTimeZone *utc2 = g_time_zone_new_utc();
	GTimeZone *cet = g_time_zone_new_identifier("+01:00");

	g_assert_true(birb_time_zone_equal(utc1, utc2));
	g_assert_false(birb_time_zone_equal(utc1, cet));

	g_time_zone_unref(utc1);
	g_time_zone_unref(utc2);
	g_time_zone_unref(cet);
}

/******************************************************************************
 * set tests
 *****************************************************************************/
static void
test_birb_time_zone_set_null_null(void) {
	GTimeZone *tz = NULL;
	g_assert_false(birb_time_zone_set(&tz, NULL));
}

static void
test_birb_time_zone_set_null_nonnull(void) {
	GTimeZone *tz = NULL;
	GTimeZone *tz1 = NULL;
	gboolean ret = FALSE;

	tz1 = g_time_zone_new_utc();
	ret = birb_time_zone_set(&tz, tz1);
	g_assert_true(ret);

	g_assert_true(tz == tz1);

	g_clear_pointer(&tz, g_time_zone_unref);
	g_clear_pointer(&tz1, g_time_zone_unref);
}

static void
test_birb_time_zone_set_nonnull_null(void) {
	GTimeZone *tz = NULL;
	gboolean ret = FALSE;

	tz = g_time_zone_new_utc();
	ret = birb_time_zone_set(&tz, NULL);
	g_assert_true(ret);

	g_assert_null(tz);
}

static void
test_birb_time_zone_set_nonnull_nonnull(void) {
	GTimeZone *tz = NULL;
	GTimeZone *tz1 = NULL;
	gboolean ret = FALSE;

	tz = g_time_zone_new_identifier("+02:00");
	tz1 = g_time_zone_new_identifier("-08:00");

	ret = birb_time_zone_set(&tz, tz1);
	g_assert_true(ret);

	g_assert_true(tz == tz1);

	g_clear_pointer(&tz, g_time_zone_unref);
	g_clear_pointer(&tz1, g_time_zone_unref);
}


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

	g_test_add_func("/time-zone/clear/null", test_birb_time_zone_clear_null);
	g_test_add_func("/time-zone/clear/nonnull", test_birb_time_zone_clear_nonnull);

	g_test_add_func("/time-zone/compare/null", test_birb_time_zone_compare_null);
	g_test_add_func("/time-zone/compare/nonnull",
	                test_birb_time_zone_compare_nonnull);

	g_test_add_func("/time-zone/equal/null", test_birb_time_zone_equal_null);
	g_test_add_func("/time-zone/equal/nonnull", test_birb_time_zone_equal_nonnull);

	g_test_add_func("/time-zone/set/null-null",
	                test_birb_time_zone_set_null_null);
	g_test_add_func("/time-zone/set/null-nonnull",
	                test_birb_time_zone_set_null_nonnull);
	g_test_add_func("/time-zone/set/nonnull-null",
	                test_birb_time_zone_set_nonnull_null);
	g_test_add_func("/time-zone/set/nonnull-nonnull",
	                test_birb_time_zone_set_nonnull_nonnull);

	return g_test_run();
}
