/* 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 "globals.h"
#include "sync.h"
#include "arg.h"
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <string.h>

#define MAXFILESZ 1024 * 1024

void log_commandline(int argc, char *argv[])
{
	for (int i = 0; i < argc; i++) {
		test_log("%s ", argv[i]);
	}
	test_log("\n");
}

int main(int _argc, char *_argv[])
{
	(void) _argc; /* unused */
	char prog[] = "lcsync";
	char src1[] = "0000-0028.src.tmp.XXXXXX";
	char src2[] = "0000-0028.src.tmp.XXXXXX";
	char *dstpath1, *dstpath2;
	char *dir = NULL;
	char **argv;
	char *argv1[] = { prog, "-b", src1, src2, NULL, NULL };
	size_t sz1, sz2;
	int argc1 = sizeof argv1 / sizeof argv1[0] - 1;
	int argc, fd, rc;

	test_name("commandline: sync two local files into directory, then scratch and resync");

	/* create test files */
	sz1 = arc4random_uniform(MAXFILESZ);
	fd = test_data_file(src1, sz1, TEST_TMP | TEST_RND);
	close(fd);
	sz2 = arc4random_uniform(MAXFILESZ);
	fd = test_data_file(src2, sz2, TEST_TMP | TEST_RND);
	close(fd);

	/* create destination directory */
	rc = test_createtestdir(basename(_argv[0]), &dir, "dst");
	if (!test_assert(rc == 0, "test_createtestdir()")) return test_status;
	argv1[4] = dir;

	rc = snprintf(NULL, 0, "%s/%s", dir, src1) + 1;
	dstpath1 = malloc(rc);
	rc = snprintf(dstpath1, rc, "%s/%s", dir, src1);

	rc = snprintf(NULL, 0, "%s/%s", dir, src2) + 1;
	dstpath2 = malloc(rc);
	rc = snprintf(dstpath2, rc, "%s/%s", dir, src2);

	/* sync */
	argc = argc1; argv = argv1;
	log_commandline(argc, argv);
	test_assert(arg_parse(&argc, &argv) == 0, "arg_parse()");
	test_assert(action(&argc, argv) == 0, "action()");

	/* verify */
	test_assert(test_file_match(src1, dstpath1) == 0, "test_file_match(): dst matches src (1)");
	test_assert(test_file_match(src2, dstpath2) == 0, "test_file_match(): dst matches src (2)");

	/* scratch destination files, resync */
	test_file_scratch(dstpath1, 0, sz1);
	test_file_scratch(dstpath2, 0, sz2);
	test_assert(test_file_match(src1, dstpath1) != 0, "test_file_match(): dst is scratched (1)");
	test_assert(test_file_match(src2, dstpath2) != 0, "test_file_match(): dst is scratched (2)");

	/* resync */
	argc = argc1; argv = argv1;
	log_commandline(argc, argv);
	test_assert(arg_parse(&argc, &argv) == 0, "arg_parse()");
	test_assert(action(&argc, argv) == 0, "action()");

	/* verify (2nd pass) */
	test_assert(test_file_match(src1, dstpath1) == 0, "test_file_match(): dst matches src (1)");
	test_assert(test_file_match(src2, dstpath2) == 0, "test_file_match(): dst matches src (2)");

	free(dir); free(dstpath1); free(dstpath2);
	return test_status;
}
