/*
 * Copyright (c) 2018 Pushpal Sidhu
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * @filesystem
 * @brief test_filesystem
 * Demonstrates the ZEPHYR File System APIs
 */

#include "test_fat.h"

static int delete_it(const char *path, int quiet)
{
	int res = 0;
	if (check_file_dir_exists(path)) {
		res = fs_unlink(path);
		if (res && !quiet) {
			TC_PRINT("Couldn't delete %s [%d]\n", path, res);
		}
	}

	return res;
}

static int create_file(const char *path)
{
	struct fs_file_t fp;
	int res = 0;
	if (!check_file_dir_exists(path)) {
		res = fs_open(&fp, path);
		if (!res) {
			res = fs_close(&fp);
		} else {
			TC_PRINT("Couldn't open %s [%d]\n", path, res);
		}
	}

	return res;
}

static int create_dir(const char *path)
{
	int res = 0;
	if (!check_file_dir_exists(path)) {
		res = fs_mkdir(path);
		if (res) {
			TC_PRINT("Couldn't create %s [%d]\n", path, res);
		}
	}

	return res;
}


static int test_rename_dir(void)
{
	const char *dn = FATFS_MNTP"/td";
	const char *ndn = FATFS_MNTP"/ntd";
	int res = TC_FAIL;

	TC_PRINT("\nRename directory tests:\n");

	if (delete_it(dn, 0) || delete_it(ndn, 0)) {
		goto cleanup;
	}

	/* Rename non-existing dir to non-existing dir */
	res = fs_rename(dn, ndn);
	if (!res) {
		TC_PRINT("Renamed non-existent directory\n");
		res = TC_FAIL;
		goto cleanup;
	}

	/* Rename existing dir to non-existing dir */
	res = create_dir(dn);
	if (!!res) {
		goto cleanup;
	}

	res = fs_rename(dn, ndn);
	if (!!res ||
	    !check_file_dir_exists(ndn) ||
	    check_file_dir_exists(dn)) {
		TC_PRINT("Renaming %s to %s failed [%d]\n", dn, ndn, res);
		res = TC_FAIL;
		goto cleanup;
	}

	/* Rename existing file to existing file */
	create_file(dn);
	res = fs_rename(dn, ndn);
	if (!!res ||
	    !check_file_dir_exists(ndn) ||
	    check_file_dir_exists(dn)) {
		TC_PRINT("Renaming %s to %s failed [%d]\n", dn, ndn, res);
		res = TC_FAIL;
		goto cleanup;
	}

cleanup:
	delete_it(dn, 1);
	delete_it(ndn, 1);

	return res;
}

static int test_rename_file(void)
{
	const char *fn = FATFS_MNTP"/tf.txt";
	const char *nfn = FATFS_MNTP"/ntf.txt";
	int res = TC_FAIL;

	TC_PRINT("\nRename file tests:\n");

	if (delete_it(fn, 0) || delete_it(nfn, 0)) {
		goto cleanup;
	}

	/* Rename non-existing file to non-existing file */
	res = fs_rename(fn, nfn);
	if (!res) {
		TC_PRINT("Renamed non-existent file\n");
		res = TC_FAIL;
		goto cleanup;
	}

	/* Rename existing file to non-existing file */
	res = create_file(fn);
	if (!!res) {
		goto cleanup;
	}

	res = fs_rename(fn, nfn);
	if (!!res ||
	    !check_file_dir_exists(nfn) ||
	    check_file_dir_exists(fn)) {
		TC_PRINT("Renaming %s to %s failed [%d]\n", fn, nfn, res);
		res = TC_FAIL;
		goto cleanup;
	}

	/* Rename existing file to existing file */
	create_file(fn);
	res = fs_rename(fn, nfn);
	if (!!res ||
	    !check_file_dir_exists(nfn) ||
	    check_file_dir_exists(fn)) {
		TC_PRINT("Renaming %s to %s failed [%d]\n", fn, nfn, res);
		res = TC_FAIL;
		goto cleanup;
	}

cleanup:
	delete_it(fn, 1);
	delete_it(nfn, 1);

	return res;
}

void test_fat_rename(void)
{
	zassert_true(test_rename_file() == TC_PASS, NULL);
	zassert_true(test_rename_dir() == TC_PASS, NULL);
}
