// Bastard File System
// (C) 2007 Rene Schickbauer
//
// The Bastard File System (BFS) is a small virtual FS for Applications
// that would normally use Tarballs and/or Zipfiles but have to dynamically
// change its contents
//
// WARNING: This is still ALPHA QUALITY CODE! Use with care!
//
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bfs.h"

#define IMAGE_FNAME "bfs_test.img"

int main(int ARGC, char **ARGV) {
    
	// Ignore "unused variables" Warning
	if(ARGV) {
		ARGC = ARGC + 0;
	}
	
    sBFS* handle;
    
    handle =  bfsGetNewHandle();
    if(!handle) {
        printf("ERROR: Couldn't get a handle!\n");
        exit(2);
    }
    
    if(!bfsNew(handle, IMAGE_FNAME, 300)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
    }

    if(!bfsOpen(handle, IMAGE_FNAME)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
    }

 // TESTS
	
    if(!bfsMakeDir(handle, "/hallo")) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	if(!bfsMakeDir(handle, "/hallo/welt1")) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}			
	if(!bfsMakeDir(handle, "/hallo/welt1/unterwelt1")) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}

    if(!bfsMakeDir(handle, "/hello")) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
    if(!bfsMakeDir(handle, "/hello/world")) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	
	char eng[] = "kjhasdfkjhasdflkjh asdf8i4qur8 4dfb c9d8zfdsh";
	char ger[] = "sadkfjh asdkfjh asdkf hasdjfh kqwehf khjewfjh sdjkfh askljdfh"
	             "asdfh asdkfjh asdfh asdfh askldfjh askldjfhakljjsdfh asdkljfh"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "ajksrerth 43nbtkjwerbgkjwerhtjkwehrtjkhwejkrthkjwehrtkjwherth";
	char esp[] = "sadkfjh asdkfjh asdkf hasdjfh kqwehf khjewfjh sdjkfh askljdfh"
	             "asdfh asdkfjh asdfh asdfh askldfjh askldjfhakljjsdfh asdkljfh"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "iuotriwouer tzwertuiz wertiuowez rtiuwertzuweirtuiowreztiuoiu"
	             "asdfkhj ert uweitr wbergf 254k 45k 435k ljh234kj5sd9fzsdfjhsf"
	             "asdkfjh awerkjh qewrkqjweh r dsfjhqwefkjh qweriuz qwefhasdfkj"
	             "sdjkh werbwekrbfkjsdfvhuiowrezg b24t5b k4tklj4h tkjleerh gtjh"
	             "erkljh wb43tbdfnmbgsdf8ouv89p54tjih45tk bsdfvnjksdfgkjhwert4e"
	             "serjk4ewrbnqwer qjkwerh ewr8943r89pxycvhb sdcv98z34tß0ß0üh re"
	             "ajksrerth 43nbtkjwerbgkjwerhtjkwehrtjkhwejkrthkjwehrtkjwherth";	             
	             
	             
	char tmp[3000];
	FILEDATA file;
	
	printf("File-Lengths: eng %d  ger: %d  esp %d\n", (int)strlen(eng), (int)strlen(ger), (int)strlen(esp));
	
	// Write files
	file.data = eng;
	file.length = strlen(eng);
    if(!bfsWriteFile(handle, "/hello/world/eng", &file)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	
	file.data = ger;
	file.length = strlen(ger);
    if(!bfsWriteFile(handle, "/hallo/welt1/unterwelt1/ger", &file)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}

	file.data = esp;
	file.length = strlen(esp);
    if(!bfsWriteFile(handle, "/esp", &file)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	// Overwrite itself!
    if(!bfsWriteFile(handle, "/esp", &file)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	
	// Now, read back ger to tmp and check
	file.data = tmp;
	file.length = 0;
    if(!bfsReadFile(handle, "/hallo/welt1/unterwelt1/ger", &file)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	}
	if(file.length != (int)strlen(ger)) {
        printf("ERROR: File length of ger is %d but read as %d\n", (int)strlen(ger), file.length);
        exit(2);
    }
	if(strncmp(tmp, ger, file.length) != 0) {
        printf("ERROR: File ger differs!\n");
        exit(2);
    }

        
	

    if(!bfsDumpDirTree(handle)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
	} else {
		printf("END-OF-LIST\n");
	}
   
// END OF TESTS
    

    if(!bfsClose(handle)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
    }

    if(!bfsCloseHandle(handle)) {
        printf("ERROR: %s\n", getLastError(handle));
        exit(2);
    }

	printf("FIN\n");  
    return 0;    
}

#if WIN32

#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <fstream>

void RedirectIOToConsole()
{
	int hConHandle;
	long lStdHandle;
	CONSOLE_SCREEN_BUFFER_INFO coninfo;
	FILE *fp;

	// allocate a console for this app

	AllocConsole();
	// set the screen buffer to be big enough to let us scroll text

	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&coninfo);
	coninfo.dwSize.Y = 40;
	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),	coninfo.dwSize);

	// redirect unbuffered STDOUT to the console

	lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

	fp = _fdopen( hConHandle, "w" );

	*stdout = *fp;
	setvbuf( stdout, NULL, _IONBF, 0 );

	// redirect unbuffered STDIN to the console
	lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

	fp = _fdopen( hConHandle, "r" );
	*stdin = *fp;
	setvbuf( stdin, NULL, _IONBF, 0 );

	// redirect unbuffered STDERR to the console

	lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
	fp = _fdopen( hConHandle, "w" );
	*stderr = *fp;
	setvbuf( stderr, NULL, _IONBF, 0 );
}

void RedirectIOToFiles()
{
	int hConHandle;
	long lStdHandle;
	FILE *fp;

	// allocate a console for this app


	// redirect unbuffered STDOUT to the console

	fp = fopen( "stdoutstderr_bfstest.txt", "w" );

	*stdout = *fp;
	setvbuf( stdout, NULL, _IONBF, 0 );

	// redirect unbuffered STDERR to the console
	*stderr = *fp;
	setvbuf( stderr, NULL, _IONBF, 0 );
}


int WINAPI WinMain(  HINSTANCE hInstance,      // handle to current instance
  HINSTANCE hPrevInstance,						// handle to previous instance
  LPSTR lpCmdLine,								// command line
  int nCmdShow									// show state
  )
{
	int argc = 0;
	int i=0;
	if (lpCmdLine[0]) // at least one paramteter
		argc = 1;
	while (lpCmdLine[i])
	{
		if (lpCmdLine[i] == ' ')
			argc++;
		i++;
	}
	argc++;  // add app name

	char** argv = (char**)malloc(argc*sizeof(char*));
	char appName[500];
	GetModuleFileNameA(0, appName, sizeof(appName));
	char* p;
	
	while(p= strrchr(appName,'\\'))
		*p= '/';
	p= argv[0] = (char*)malloc(strlen(appName)+10);
	strcpy(p,appName);

	i = argc-1;
	char* strptr = strrchr(lpCmdLine, ' ');
	while (strptr)
	{
		p=argv[i] = (char*)malloc(strlen(strptr+1)+10);
		strcpy( p,strptr+1);
		*strptr = '\0';
		i--;
		strptr = strrchr(lpCmdLine, ' ');
	}
	if (lpCmdLine[0])
	{
		p=argv[1] = (char*)malloc(strlen(lpCmdLine)+1);
		strcpy(p,lpCmdLine);
	}
	//RedirectIOToConsole();
	RedirectIOToFiles();

	return main(argc, argv);
}
#endif // WIN32
