#include <stdio.h>
#include <string.h>
#include <windows.h>

char buf[1048576] = {0};

int main(int argc, char *argv[])
{
	int nmb;
	int res;
	int num_iterations;
	char *filename, *curfilename;
	char tmpfilename[MAX_PATH];
	FILE *fh;
	char do_rename;
	WIN32_FIND_DATA FindFileData;

	if (argc < 4)
		{ printf("Usage: %s {filename} {size_mb} {num_iterations}", argv[0]); return 1; }

	filename = argv[1];

	nmb = atoi(argv[2]);
	if (nmb < 1) nmb = 1;

	num_iterations = atoi(argv[3]);
	if (num_iterations < 1) num_iterations = 1;

	do_rename = (strcmp(argv[argc - 1], "rename") == 0);
	
	for (int i = 1; i <= num_iterations; i++) {
		printf("iteration %d\n", i);

		fh = fopen(filename, "wb");
		if (fh == NULL)
			{ printf("first fopen() failed (%d)\n", errno); return 1; }

		for (int n = 0; n <= nmb; n++) {
			if (fwrite(buf, 1, sizeof(buf), fh) != sizeof(buf))
				{ printf("fwrite() failed (%d)\n", errno); return 1; }
		}

		res = fclose(fh);
		if (res < 0)
			{ printf("first fclose() failed (%d)\n", errno); return 1; }

		curfilename = filename;
		if (do_rename)
		{
			sprintf(tmpfilename, "%s.tmp", filename);
			res = MoveFileEx(filename, tmpfilename, MOVEFILE_REPLACE_EXISTING); // from dirmod.c
			if (res == 0)
				{ printf("MoveFileEx() failed (%d)\n", errno); return 1; }
			curfilename = tmpfilename;
		}
			
		res = unlink(curfilename);
		if (res < 0)
			{ printf("first unlink() failed (%d)\n", errno); return 1; }

		fh = fopen(filename, "w");
		if (fh == NULL)
			{ printf("fopen() after unlink() failed (%d)\n", errno); return 2; }

		res = fclose(fh);
		if (res < 0)
			{ printf("fclose() failed (%d)\n", errno); return 1; }

		res = unlink(filename);
		if (res < 0)
			{ printf("unlink() failed (%d)\n", errno); return 1; }

		// Assuming {filename} is in the current directory
		HANDLE hFind = FindFirstFile("*.*", &FindFileData);
		if (hFind == INVALID_HANDLE_VALUE)
		  { printf("FindFirstFile() failed (%d)\n", errno); return 1; }
		do {
			HANDLE hFile = CreateFile(FindFileData.cFileName,
				GENERIC_READ, (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
				NULL, OPEN_EXISTING, 0, NULL);
			if (hFile != INVALID_HANDLE_VALUE)
				CloseHandle(hFile);
		} while(FindNextFile(hFind, &FindFileData));
		FindClose(hFind);
	}
	return 0;
}