/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2023 Brett Sheffield <bacs@librecast.net> */

#include "test.h"
#include "testdata.h"
#include <librecast/sync.h>
#include <errno.h>

#define TEST_SIZE 42 * 1024 + 1
/* nice powers of two hide bugs - ensure test size is odd */
_Static_assert(TEST_SIZE % 2, "TEST_SIZE must be an odd number");

int main(void)
{
	uint8_t *src, *dst;
	int rc;

	test_name("lc_memsync()");

	rc = lc_memsync(NULL, NULL, 0, NULL, NULL, NULL, 0);
	test_assert(rc == -1, "size must be greater than zero");

	/* allocate some memory to work with */
	src = malloc(TEST_SIZE);
	test_assert(src != NULL, "allocate source");
	if (!src) return TEST_FAIL;
	dst = malloc(TEST_SIZE);
	memset(dst, 0, TEST_SIZE);
	test_assert(dst != NULL, "allocate destination");

	test_assert(!test_random_bytes(src, TEST_SIZE), "randomize src");
	test_assert(memcmp(dst, src, TEST_SIZE), "dst and src differ");

	/* sync */
	rc = lc_memsync(dst, src, TEST_SIZE, NULL, NULL, NULL, 0);
	test_assert(rc == 0, "lc_memsync() returns 0 (SUCCESS)");
	test_assert(!memcmp(dst, src, TEST_SIZE), "dst matches src");

	/* scratch source, sync again */
	test_assert(!test_random_bytes(src, 1), "scratch src");
	test_assert(!test_random_bytes(src + 5 * 1024, 3), "scratch src");
	test_assert(!test_random_bytes(src + 15 * 1024, 3), "scratch src");
	test_assert(memcmp(dst, src, TEST_SIZE), "dst and src differ");
	test_assert(!lc_memsync(dst, src, TEST_SIZE, NULL, NULL, NULL, 0), "lc_memsync");
	test_assert(!memcmp(dst, src, TEST_SIZE), "dst matches src");

	/* clean up */
	free(dst);
	free(src);

	return test_status;
}
