/* tests for osmo_sockaddr_str API of libmsomcore */
/*
 * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 *
 * Author: neels@hofmeyr.de
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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.
 *
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/core/utils.h>
#include <netinet/in.h>

struct osmo_sockaddr_str oip_data[] = {
	{ .af = AF_INET, .ip = "1.2.3.4", .port = 5 },
	{ .af = AF_INET, .ip = "0.0.0.0", .port = 0 },
	{ .af = AF_INET, .ip = "255.255.255.255", .port = 65535 },
	{ .af = AF_INET, .ip = "0.0.0.256", .port = 1 },
	{ .af = AF_INET, .ip = "not an ip address", .port = 1 },
	{ .af = AF_INET6, .ip = "1:2:3::4", .port = 5 },
	{ .af = AF_INET6, .ip = "::", .port = 0 },
	{ .af = AF_INET6, .ip = "::1", .port = 0 },
	{ .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 },
	{ .af = AF_INET6, .ip = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", .port = 65535 },
	{ .af = AF_INET6, .ip = "::fffff", .port = 1 },
	{ .af = AF_INET6, .ip = "not an ip address", .port = 1 },

	{ .af = AF_INET6, .ip = "1.2.3.4", .port = 5 },
	{ .af = AF_INET, .ip = "1:2:3::4", .port = 5 },
	{ .af = AF_UNSPEC, .ip = "1.2.3.4", .port = 5 },
	{ .af = AF_INET, .ip = "", .port = 5 },
	{ .af = AF_INET6, .ip = "", .port = 5 },
	{ .af = AF_INET, .ip = "1.2.3.4", .port = 0 },
	{ .af = AF_INET, .ip = "1.2.3:4:5", .port = 0 },
	{ .af = AF_INET6, .ip = "::1:10.9.8.7", .port = 1 },
	{ .af = AF_INET, .ip = "0.0.0.0", .port = 5 },
	{ .af = AF_INET6, .ip = "::", .port = 5 },
	{ .af = AF_INET6, .ip = "0::", .port = 5 },
};

const char *af_name(int af)
{
	switch (af) {
	case AF_INET:
		return "AF_INET";
	case AF_INET6:
		return "AF_INET6";
	case AF_UNSPEC:
		return "AF_UNSPEC";
	default:
		return "?";
	}
}

static inline const char *rc_name(int rc)
{
	switch (rc) {
	case -EINVAL:
		return "rc == -EINVAL";
	case -EAFNOSUPPORT:
		return "rc == -EAFNOSUPPORT";
	case 0:
		return "rc == 0";
	default:
		return rc < 0 ? "rc < 0" : "rc > 0";
	}
}

void dump_oip(const struct osmo_sockaddr_str *oip)
{
	printf("{ .af = %s, .ip = %s, .port = %u }\n", af_name(oip->af), osmo_quote_str(oip->ip, -1), oip->port);
}

void sockaddr_str_test_conversions(void)
{
	int i;
	char buf[1024];

#define hexdump(what) \
	osmo_hexdump_buf(buf, sizeof(buf), (void*)(&what), sizeof(what), "", false)

	for (i = 0; i < ARRAY_SIZE(oip_data); i++) {
		struct osmo_sockaddr_str *x = &oip_data[i];
		int rc;
		printf("\n\n");
		dump_oip(x);

		printf("  OSMO_SOCKADDR_STR_FMT: '" OSMO_SOCKADDR_STR_FMT "'\n",
		       OSMO_SOCKADDR_STR_FMT_ARGS(x));
		printf("  osmo_sockaddr_str_is_set() = %s\n", osmo_sockaddr_str_is_set(x) ? "true" : "false");
		printf("  osmo_sockaddr_str_is_nonzero() = %s\n", osmo_sockaddr_str_is_nonzero(x) ? "true" : "false");

		{
			struct in_addr a = {};

			rc = osmo_sockaddr_str_to_in_addr(x, &a);
			printf("  osmo_sockaddr_str_to_in_addr() %s in_addr=%s\n", rc_name(rc), hexdump(a));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_in_addr(&back, &a, x->port);
				printf("   -> osmo_sockaddr_str_from_in_addr() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			struct in6_addr a = {};

			rc = osmo_sockaddr_str_to_in6_addr(x, &a);
			printf("  osmo_sockaddr_str_to_in6_addr() %s in6_addr=%s\n", rc_name(rc), hexdump(a));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_in6_addr(&back, &a, x->port);
				printf("   -> osmo_sockaddr_str_from_in6_addr() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			uint32_t a = 0;

			rc = osmo_sockaddr_str_to_32(x, &a);
			printf("  osmo_sockaddr_str_to_32() %s uint8_t[4]=[ %s]\n", rc_name(rc),
			       osmo_hexdump((void*)&a, sizeof(a)));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_32(&back, a, x->port);
				printf("   -> osmo_sockaddr_str_from_32() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			uint32_t a = 0;

			rc = osmo_sockaddr_str_to_32h(x, &a);
			printf("  osmo_sockaddr_str_to_32h() %s uint8_t[4]=[ %s]\n", rc_name(rc),
			       osmo_hexdump((void*)&a, sizeof(a)));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_32h(&back, a, x->port);
				printf("   -> osmo_sockaddr_str_from_32h() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			struct sockaddr_in a = {};

			rc = osmo_sockaddr_str_to_sockaddr_in(x, &a);
			printf("  osmo_sockaddr_str_to_sockaddr_in() %s sockaddr_in=%s\n", rc_name(rc), hexdump(a));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_sockaddr_in(&back, &a);
				printf("   -> osmo_sockaddr_str_from_sockaddr_in() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			struct sockaddr_in6 a = {};

			rc = osmo_sockaddr_str_to_sockaddr_in6(x, &a);
			printf("  osmo_sockaddr_str_to_sockaddr_in6() %s sockaddr_in6=%s\n", rc_name(rc), hexdump(a));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_sockaddr_in6(&back, &a);
				printf("   -> osmo_sockaddr_str_from_sockaddr_in6() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			struct sockaddr_storage a = {};

			rc = osmo_sockaddr_str_to_sockaddr(x, &a);
			printf("  osmo_sockaddr_str_to_sockaddr() %s sockaddr_storage=%s\n", rc_name(rc), hexdump(a));

			if (rc == 0) {
				struct osmo_sockaddr_str back;
				rc = osmo_sockaddr_str_from_sockaddr(&back, &a);
				printf("   -> osmo_sockaddr_str_from_sockaddr() %s ", rc_name(rc));
				dump_oip(&back);
				if (memcmp(x, &back, sizeof(back)))
					printf("      DIFFERS!\n");
			}
		}

		{
			struct osmo_sockaddr_str from_str;
			rc = osmo_sockaddr_str_from_str(&from_str, x->ip, x->port);
			printf("  osmo_sockaddr_str_from_str() %s ", rc_name(rc));
			dump_oip(&from_str);
			if (rc == 0 && memcmp(x, &from_str, sizeof(from_str)))
				printf("      DIFFERS!\n");
		}
	}

}

static void test_osmo_sockaddr_str_cmp(void)
{
	int i;
	printf("\n\n%s\n", __func__);
	for (i = 0; i < ARRAY_SIZE(oip_data); i++) {
		/* use a copy to not hit the pointer comparison in osmo_sockaddr_str_cmp(). */
		struct osmo_sockaddr_str _a = oip_data[i];
		struct osmo_sockaddr_str *a = &_a;
		int j;
		printf("[%2d]\n", i);

		for (j = 0; j < ARRAY_SIZE(oip_data); j++) {
			struct osmo_sockaddr_str *b = &oip_data[j];
			int ip_rc = osmo_sockaddr_str_cmp(a, b);
			printf("  osmo_sockaddr_str_cmp(): " OSMO_SOCKADDR_STR_FMT "%s %s " OSMO_SOCKADDR_STR_FMT "%s\n",
			       OSMO_SOCKADDR_STR_FMT_ARGS(a),
			       osmo_sockaddr_str_is_nonzero(a) ? "" : "(zero)",
			       ip_rc < 0? "<" : (ip_rc == 0 ? "==" : ">" ),
			       OSMO_SOCKADDR_STR_FMT_ARGS(b),
			       osmo_sockaddr_str_is_nonzero(b) ? "" : "(zero)");
		}
	}
}

int main(int argc, char **argv)
{
	sockaddr_str_test_conversions();
	test_osmo_sockaddr_str_cmp();
	return 0;
}

