/*
 * Ibis - IRCv3 Library
 * Copyright (C) 2022-2025 Ibis Developers
 *
 * Ibis is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This library 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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib.h>

#include <birb.h>

#include <ibis.h>

typedef struct {
	const char *hostname;
	const char *to_string;
} TestIbisDCCHostData;

/******************************************************************************
 * Tests
 *****************************************************************************/
static void
test_ibis_dcc_host_ipv4(gconstpointer data) {
	const TestIbisDCCHostData *host_data = data;
	GInetAddress *address = NULL ;
	GSocketFamily family = G_SOCKET_FAMILY_INVALID;
	char *serialized = NULL;
	char *to_string = NULL;

	address = ibis_dcc_host_parse(host_data->hostname);
	birb_assert_type(address, G_TYPE_INET_ADDRESS);

	family = g_inet_address_get_family(address);
	g_assert_cmpuint(family, ==, G_SOCKET_FAMILY_IPV4);

	to_string = g_inet_address_to_string(address);
	g_assert_cmpstr(to_string, ==, host_data->to_string);
	g_free(to_string);

	serialized = ibis_dcc_host_to_string(address);
	g_assert_cmpstr(serialized, ==, host_data->hostname);

	g_assert_finalize_object(address);
	g_free(serialized);
}

static void
test_ibis_dcc_host_ipv6(gconstpointer data) {
	GInetAddress *address = NULL ;
	GSocketFamily family = G_SOCKET_FAMILY_INVALID;
	char *serialized = NULL;
	const char *host = data;

	address = ibis_dcc_host_parse(host);
	birb_assert_type(address, G_TYPE_INET_ADDRESS);

	family = g_inet_address_get_family(address);
	g_assert_cmpuint(family, ==, G_SOCKET_FAMILY_IPV6);

	serialized = ibis_dcc_host_to_string(address);
	g_assert_cmpstr(serialized, ==, host);

	g_assert_finalize_object(address);
	g_free(serialized);
}

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

	g_test_set_nonfatal_assertions();

	g_test_add_data_func("/ibis/dcc/host/ipv4/localhost",
	                     &(const TestIbisDCCHostData){"2130706433", "127.0.0.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/1.0.0.1",
	                     &(const TestIbisDCCHostData){"16777217", "1.0.0.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/1.1.1.1",
	                     &(const TestIbisDCCHostData){"16843009", "1.1.1.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/8.8.4.4",
	                     &(const TestIbisDCCHostData){"134743044", "8.8.4.4"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/8.8.8.8",
	                     &(const TestIbisDCCHostData){"134744072", "8.8.8.8"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/10.0.0.1",
	                     &(const TestIbisDCCHostData){"167772161", "10.0.0.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/172.16.0.1",
	                     &(const TestIbisDCCHostData){"2886729729", "172.16.0.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/192.168.0.1",
	                     &(const TestIbisDCCHostData){"3232235521", "192.168.0.1"},
	                     test_ibis_dcc_host_ipv4);
	g_test_add_data_func("/ibis/dcc/host/ipv4/192.168.1.1",
	                     &(const TestIbisDCCHostData){"3232235777", "192.168.1.1"},
	                     test_ibis_dcc_host_ipv4);

	g_test_add_data_func("/ibis/dcc/host/ipv6/localhost",
	                     "::1",
	                     test_ibis_dcc_host_ipv6);
	g_test_add_data_func("/ibis/dcc/host/ipv6/cloudflare-dns-1",
	                     "2606:4700:4700::1001",
	                     test_ibis_dcc_host_ipv6);
	g_test_add_data_func("/ibis/dcc/host/ipv6/cloudflare-dns-2",
	                     "2606:4700:4700::1111",
	                     test_ibis_dcc_host_ipv6);
	g_test_add_data_func("/ibis/dcc/host/ipv6/google-dns-1",
	                     "2001:4860:4860::8888",
	                     test_ibis_dcc_host_ipv6);
	g_test_add_data_func("/ibis/dcc/host/ipv6/google-dns-2",
	                     "2001:4860:4860::8844",
	                     test_ibis_dcc_host_ipv6);

	return g_test_run();
}
