/* $Id: t_tmpfileplus.c $ */
/*
* $Date: 2016-06-01 03:31Z $
* $Revision: 2.0.0 $
* $Author: dai $
*/

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
* <http://www.di-mgt.com.au/contact/>.
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <assert.h>
#include "tmpfileplus.h"

/* Choose test directory suitable for Windows or Linux */
#ifdef _WIN32
#define TEST_DIR "C:\\Test"
#else
#define TEST_DIR "./Test"
#endif

int test_tempfile(FILE *fp, char *pathname)
{
	time_t now;
	clock_t clk;

	printf("\nTESTING: ");
	printf("pathname=[%s]\n", (pathname ? pathname : "NULL"));
	if (fp) {
		int i;
		int c;
		printf("fp is valid\n");
		/* Write the time now and the alphabet to our temp file */
		time(&now);
		fprintf(fp, "%s", ctime(&now));
		clk = clock();
		fprintf(fp, "clock=%#x ms\n", (unsigned)clk);
		for (i = 0; i < 26; i++)
			fputc('A'+i, fp);

		rewind(fp);
		printf("DATA:\n");
		while ((c = fgetc(fp)) != EOF)
		{
			putchar(c);
		}
		printf("\n");

	}
	else {
		printf("ERROR: fp is not valid!\n");
		assert(fp);
	}

	return 0;
}

int test_closedfile(const char *tempfile, int keep)
{
	FILE *fp;
	if (tempfile) {
		printf("After closing...\n");
		/* See if file still exists */
		fp = fopen(tempfile, "rb");
		if (fp) {
			printf("File '%s' EXISTS%s\n", tempfile, (keep ? ", as expected" : " ERROR!"));
			fclose(fp);
			assert(keep);
		}
		else {
			printf("File '%s' DOES NOT exist%s\n", tempfile, (!keep ? ", as expected" : " ERROR!"));
			assert(!keep);
		}
	}
	return 0;
}


int main(void)
{
	FILE *fp;
	char *pathname;
	int keep;
	char pathbuf[FILENAME_MAX];
	size_t flen;

	/* Test with no pathname, like tmpfile() */
	fp = tmpfileplus(NULL, NULL, NULL, 0);
	test_tempfile(fp, NULL);
	fclose(fp);

	fp = tmpfileplus_f(NULL, NULL, NULL, 0, 0);
	test_tempfile(fp, NULL);
	fclose(fp);

	/* Test with a pathname */
	fp = tmpfileplus(NULL, NULL, &pathname, 0);
	test_tempfile(fp, pathname);
	fclose(fp);
	test_closedfile(pathname, 0);
	if (pathname) free(pathname);

	fp = tmpfileplus_f(NULL, NULL, pathbuf, sizeof(pathbuf), 0);
	test_tempfile(fp, pathbuf);
	fclose(fp);
	test_closedfile(pathbuf, 0);
	/* Remember this "standard" length for later */
	flen = strlen(pathbuf);
	assert(flen > 0);

	/* Test with a given prefix */
	fp = tmpfileplus(NULL, "THIS-", &pathname, 0);
	test_tempfile(fp, pathname);
	fclose(fp);
	test_closedfile(pathname, 0);
	if (pathname) free(pathname);

	fp = tmpfileplus_f(NULL, "THIS-", pathbuf, sizeof(pathbuf), 0);
	test_tempfile(fp, pathbuf);
	fclose(fp);
	test_closedfile(pathbuf, 0);

	/* Test with a specified directory
	   -- directory "C:\Test" (Windows) or "./Test" (Linux) must exist 
	   -- otherwise default is used */
	fp = tmpfileplus(TEST_DIR, "THAT~", &pathname, 0);
	test_tempfile(fp, pathname);
	fclose(fp);
	test_closedfile(pathname, 0);
	if (pathname) free(pathname);

	fp = tmpfileplus_f(TEST_DIR, "THAT~", pathbuf, sizeof(pathbuf), 0);
	test_tempfile(fp, pathbuf);
	fclose(fp);
	test_closedfile(pathbuf, 0);

	/* Test with a specified directory but keep the file */
	keep = 1;
	fp = tmpfileplus(TEST_DIR, NULL, &pathname, keep);
	test_tempfile(fp, pathname);
	fclose(fp);
	test_closedfile(pathname, keep);
	if (pathname) free(pathname);

	fp = tmpfileplus_f(TEST_DIR, NULL, pathbuf, sizeof(pathbuf), keep);
	test_tempfile(fp, pathbuf);
	fclose(fp);
	test_closedfile(pathbuf, keep);

	/* Test with too short buffer - this should fail */
	printf("\nTest with too short buffer...\n");
	pathbuf[0] = 0;
	fp = tmpfileplus_f(NULL, NULL, pathbuf, 5, 0);
	printf("fp=%p, errno=%d\n", fp, errno);
	assert(!fp);
	assert(0 == pathbuf[0]);

	/* Try an off-by-one error */
	pathbuf[0] = 0;
	fp = tmpfileplus_f(NULL, NULL, pathbuf, flen, 1);
	printf("fp=%p, errno=%d\n", fp, errno);
	assert(!fp);
	assert(0 == pathbuf[0]);

	return 0;
}