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

/* test 0118
 *
 * - generate a directory tree
 * - calculate hash for that directory
 * - change a file
 * - recalculate hash
 * - hash MUST not match
 */

#include "test.h"
#include "testdata.h"
#include <sys/types.h>
#include <errno.h>
#include <librecast/mdex.h>
#include <unistd.h>

#define MAXFILESZ 1048576
#define MAXFILES 10
#define MAXDIRS 5
#define DEPTH 3

int main(int argc, char *argv[])
{
	(void)argc;
	unsigned char root1[HASHSIZE] = "";
	unsigned char root2[HASHSIZE] = "";
	char *src = NULL, *dst = NULL;
	int rc;

	test_name("mdex_get_directory_root()");

	/* create source directory tree and files */
	rc = test_createtestdirs(basename(argv[0]), &src, &dst);
	if (!test_assert(rc == 0, "test_createtestdirs()")) return test_status;
	rc = test_createtesttree(src, MAXFILESZ, MAXFILES, MAXDIRS, DEPTH, 0);
	if (!test_assert(rc == 0, "test_createtesttree()")) goto err_free_src_dst;

	/* calculate root hash of source tree */
	rc = mdex_get_directory_root(src, root1);
	if (!test_assert(rc == 0, "mdex_get_directory_root()")) goto err_free_src_dst;

	/* create new (empty) file in src directory */
	char newfile[] = "newfile.XXXXXX";
	char owd[PATH_MAX];
	if (!test_assert(getcwd(owd, sizeof owd) != NULL, "getcwd()")) goto err_free_src_dst;
	rc = chdir(src);
	if (!test_assert(rc == 0, "chdir() %s", src)) goto err_free_src_dst;
	rc = mkstemp(newfile);
	if (!test_assert(rc != -1, "mkstemp() %s", newfile)) goto err_free_src_dst;
	close(rc);
	rc = chdir(owd);
	if (!test_assert(rc == 0, "chdir() %s", owd)) goto err_free_src_dst;

	/* (re)calculate root hash of source tree */
	rc = mdex_get_directory_root(src, root2);
	if (!test_assert(rc == 0, "mdex_get_directory_root()")) goto err_free_src_dst;

	/* root hashes differ */
	hash_hex_debug(stderr, root1, HASHSIZE);
	hash_hex_debug(stderr, root2, HASHSIZE);
	test_assert(memcmp(root1, root2, HASHSIZE), "root hashes differ");

err_free_src_dst:
	free(src); free(dst);
	return test_status;
}
