/* SPDX-License-Identifier: GPL-2.0-only */

#include <tests/test.h>
#include <string.h>
#include <stdlib.h>
#include <types.h>
#include <ip_checksum.h>

static const uint8_t test_data_simple[] = {
	0x64, 0x3b, 0x33, 0x17, 0x34, 0x74, 0x62, 0x30, 0x75, 0x73, 0xf3, 0x11, 0x30, 0x2c,
	0x34, 0x35, 0x6d, 0x39, 0x69, 0x32, 0x23, 0x24, 0x76, 0x71, 0x77, 0x30, 0x39, 0x75,
	0x76, 0x35, 0x71, 0x32, 0x40, 0x46, 0x34, 0x34, 0xBB, 0x03, 0x66, 0x52};
static const size_t test_data_simple_sz = ARRAY_SIZE(test_data_simple);
static const unsigned long test_data_simple_checksum = 0x4267;

static uint8_t test_data_zeros[1024];
static const size_t test_data_zeros_sz = ARRAY_SIZE(test_data_zeros);
static const unsigned long test_data_zeros_checksum = 0xFFFF;

static int setup_test_group(void **state)
{
	memset(test_data_zeros, 0, test_data_zeros_sz);

	return 0;
}

static void test_compute_ip_checksum_zero_length(void **state)
{
	unsigned long res = compute_ip_checksum(test_data_simple, 0);

	/* Expect checksum to be in initial state as there are were no data provided. */
	assert_int_equal(0xFFFF, res);
}

static void test_compute_ip_checksum_zero_buffer(void **state)
{
	unsigned long res = compute_ip_checksum(test_data_zeros, test_data_zeros_sz);
	assert_int_equal(test_data_zeros_checksum, res);
}

static void test_compute_ip_checksum_simple_data(void **state)
{
	unsigned long res;
	unsigned long check_res;
	const size_t helper_buffer_size = sizeof(uint8_t) * (test_data_simple_sz + 2);
	char *helper_buffer = malloc(helper_buffer_size);

	/* Self test */
	assert_non_null(helper_buffer);

	/* Expect function to generate the same checksum as stored in */
	res = compute_ip_checksum(test_data_simple, test_data_simple_sz);
	assert_int_equal(test_data_simple_checksum, res);

	/* Copy test data and checksum to new buffer. Expect computed checksum to be zero,
	   as it proves the data and the checksum are correct. */
	memcpy(helper_buffer, test_data_simple, test_data_simple_sz);
	helper_buffer[helper_buffer_size - 2] = res & 0xFF;
	helper_buffer[helper_buffer_size - 1] = (res >> 8) & 0xFF;
	check_res = compute_ip_checksum(helper_buffer, helper_buffer_size);
	assert_int_equal(0, check_res);

	free(helper_buffer);
}

static void test_add_ip_checksums_empty_values(void **state)
{
	unsigned long res;

	res = add_ip_checksums(0, 0xFFFF, 0xFFFF);
	assert_int_equal(0xFFFF, res);

	res = add_ip_checksums(1, 0xFFFF, 0xFFFF);
	assert_int_equal(0xFFFF, res);
}

static void test_add_ip_checksums(void **state)
{
	unsigned long res_1 = compute_ip_checksum(test_data_simple, test_data_simple_sz / 2);
	unsigned long res_2 = compute_ip_checksum(test_data_simple + test_data_simple_sz / 2,
						  test_data_simple_sz / 2);
	unsigned long res_sum = add_ip_checksums(test_data_simple_sz / 2, res_1, res_2);

	assert_int_equal(test_data_simple_checksum, res_sum);
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test(test_compute_ip_checksum_zero_length),
		cmocka_unit_test(test_compute_ip_checksum_zero_buffer),
		cmocka_unit_test(test_compute_ip_checksum_simple_data),

		cmocka_unit_test(test_add_ip_checksums_empty_values),
		cmocka_unit_test(test_add_ip_checksums),
	};

	return cb_run_group_tests(tests, setup_test_group, NULL);
}
