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

/* mdex symlink */

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

#define TEST_SIZE 1024 * 1024 + 5
/* 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)
{
	struct stat sb;
	char src[] = "0000-0064.src.tmp.XXXXXX";
	char dst[] = "0000-0064.dst.tmp.XXXXXX";
	unsigned char alias[HASHSIZE];
	mdex_t *mdex;
	mtree_t mtree = {0};
	mdex_entry_t entry = {0};
	size_t off = 0;
	int fds, rc;

	test_name("mdex_addfile() (symlink)");

	/* create test file */
	fds = test_data_file(src, TEST_SIZE, TEST_TMP | TEST_RND);
	test_assert(fds != -1, "test_data_file()");
	if (fds == -1) goto exit_0;
	test_assert(test_data_size(src, TEST_SIZE) == 0, "source exists and is correct size");

	off = strlen(src) - 6;
	memcpy(dst + off, src + off, 6);

	/* create dst as symlink to src */
	test_log("creating symlink '%s' => '%s'\n", dst, src);
	rc = symlink(src, dst);
	if (!test_assert(rc == 0, "symlink(): %s", strerror(errno))) goto exit_0;
	if (!test_assert(lstat(dst, &sb) != -1, "stat symlink")) goto exit_0;

	mdex = mdex_init(0);
	rc = mtree_init(&mtree, TEST_SIZE);
	if (!test_assert(rc == 0, "mtree_init() returned %i", rc)) goto err_free_mdex;

	/* add our symlink to mdex */
	rc = mdex_addfile(mdex, dst, NULL, MDEX_ALIAS);
	if (!test_assert(rc == 0, "mdex_addfile() returned %i", rc)) goto err_free_mtree;

	/* test root hash is in index */
	mdex_tree_hash_sb(alias, sizeof alias, NULL, 0, &sb, dst);
	test_log("fetching root hash\n");
	hash_hex_debug(stderr, alias, HASHSIZE);
	rc = mdex_get(mdex, alias, HASHSIZE, &entry);
	test_assert(rc == 0, "root hash found");

err_free_mtree:
	mtree_free(&mtree);
err_free_mdex:
	mdex_free(mdex);
	close(fds);
	unlink(dst);
	unlink(src);
exit_0:
	return test_status;
}
