#include "homedir.h"

#ifdef __cplusplus
extern "C"
{
#endif



#ifdef _WIN32

/*
For Unicode platforms, TCHAR is defined as synonymous with the WCHAR type.
LPSTR = char*
LPCSTR = const char*
LPWSTR = wchar_t*
LPCWSTR = const wchar_t*
LPTSTR = char* or wchar_t* depending on _UNICODE
LPCTSTR = const char* or const wchar_t* depending on _UNICODE
*/


void setup_homedir(void){
	char *dirname;
	char *name_tmp;
	char *envptr;
	size_t strlength = 1;
	size_t reqlength = 0;
	WIN32_FIND_DATA *dirptr;
	HANDLE *out;
	int ret_val = 0;
	DWORD dw;
	char *envptr;
	LPSECURITY_ATTRIBUTES write_security;
	

	//Case is ignored when looking up the environment-variable name.

	envptr = (char *)malloc( strlength * sizeof(TCHAR) );
	if(envptr == NULL){
		BenchErr("Error:", "malloc", 1);
	}
	//When using ANSI strings, the buffer size should be the string length, plus terminating null character, plus one.
	//must use TCHARs and test for == 
	while( (ret_val = ExpandEnvironmentStrings( _T("%UserProfile%"), envptr, strlength)) > strlength){
		strlength = ret_val;
		envptr = (char *)realloc( envptr, ret_val * sizeof(char) );
		if(envptr == NULL){
			BenchErr("Error:", "realloc", 1);
		}
	}
	if(ret_val == 0){
		BenchErr("Error:", "ExpandEnvironmentStrings", 1);
	}
	strlength = ret_val + strlen("\lsbench");;
	dirname = (char *)malloc( strlength );
	if(envptr == NULL){
		BenchErr("Error:", "malloc", 1);
	}
	ret_val = _snprintf(dirname, strlength, "%s%s", envptr, (char *)"\lsbench");
	if(ret_val < 0){
		BenchErr("Error: buffer not large enough", "_snprintf", 1);
	}


/*
	(void)strncpy(dirname, (const char *)envptr, strlength );
	strlength += strlen("\\lsbench");
	

	envptr = getenv("USERPROFILE");
	if(envptr == NULL){
		printf("%s: getenv - %s\n", program_invocation, strerror(errno) );
		printf("cannot determine your %%USERPROFILE%% variable, exiting!\n");
		exit(1);
	}
	strlength = strlen((const char *)envptr);
	dirname = (char *)malloc( strlength );
	(void)strncpy(dirname, (const char *)envptr, strlength );
	strlength += strlen("\\lsbench");
	dirname = (char *)realloc(dirname, strlength);
	(void)strncat(dirname, "\\lsbench", strlen("\\lsbench") );

*/

	out = FindFirstFile((LPCTSTR)dirname, dirptr); 
	if(out == INVALID_HANDLE_VALUE){
		//does not exist, create it
		BenchErr("Warn:", "FindFirstFile", 0);
		printf("creating lsbench local dir: %s\n", dirname);
		ret_val = _mkdir(dirname); //returns 0 for success
		if(ret_val != 0){
			BenchErr("Error:", "_mkdir", 1);
		}
		
	}else{
		if( FindClose(out) != 0 ){ //returns 0 for success
			BenchErr("Error:", "FindClose", 1);
		}
	}
 
	reqlength = strlength + strlen("\lsbench.conf");
	name_tmp = (char *)malloc( reqlength );
	if(name_tmp == NULL){
		BenchErr("Error:", "malloc", 1);
	}
	ret_val = _snprintf(name_tmp, reqlength, "%s%s", dirname, (char *)"\lsbench.conf");
	if(ret_val < 0){
		BenchErr("Error: buffer not large enough", "_snprintf", 1);
	}
	out = FindFirstFile((LPCTSTR)name_tmp, dirptr);
	if(out == INVALID_HANDLE_VALUE){
		//does not exist, create it
		write_security.nLength = (DWORD)sizeof(SECURITY_ATTRIBUTES);
		write_security.lpSecurityDescriptor = NULL;
		out = CreateFile((LPCTSTR)dirname, (GENERIC_READ | GENERIC_WRITE), 0, &write_security, 


	}else{
		if( FindClose(out) != 0 ){ //returns 0 for success
			BenchErr("Error:", "FindClose", 1);
		}

	}



	dirptr = opendir(dirname);
	if(dirptr == NULL){
		printf("%s: opendir - %s\n", program_invocation, strerror(errno) );
		printf("creating lsbench local dir: %s\n", dirname);
		ret_val = _mkdir(dirname); //returns 0 for success
		if(ret_val != 0){
			printf("%s: _mkdir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create directory, exiting!\n");
			exit(1);
		}
	}else{
		if( closedir(dirptr) != 0){
			printf("%s: closedir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close directory %s, exiting!\n", dirname);
			exit(1);
		}
	}

	reqlength = strlen("\\lsbench.conf") + strlength;
	name_tmp = (char *)malloc( reqlength );
	(void)strncpy(name_tmp, (const char *)dirname, strlength );
	(void)strncat(name_tmp, "\\lsbench.conf", strlen("\\lsbench.conf") );

	if( out = fopen(name_tmp, "r") ){
		if(fclose(out) != 0){
			printf("%s: fclose - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close file %s , exiting!\n", name_tmp);
			exit(1);
		}
	}else{
		if( ( out = fopen( name_tmp, "w" ) ) == NULL ) {
			printf("%s: fopen - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create file %s , exiting!\n", name_tmp);
			exit(1);
		}
		if(fprintf(out, "PORT: 3940\n") < 0 ){
			printf("%s: fprintf - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot write to file %s , exiting!\n", name_tmp);
			exit(1);
		}
		if(fclose(out) != 0){
			printf("%s: fclose - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close file %s , exiting!\n", name_tmp);
			exit(1);
		}
	}

	strlength += strlen("\\cache");
	dirname = (char *)realloc(dirname, strlength);
	(void)strncat(dirname, "\\cache", strlen("\\cache") );

	dirptr = opendir(dirname);
	if(dirptr == NULL){
		printf("%s: opendir - %s\n", program_invocation, strerror(errno) );
		printf("creating directory: %s\n", dirname);
		ret_val = _mkdir(dirname); //returns 0 for success
		if(ret_val != 0){
			printf("%s: _mkdir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create directory %s , exiting!\n", dirname);
			exit(1);
		}
	}else{
		if( closedir(dirptr) != 0){
			printf("%s: closedir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close directory %s, exiting!\n", dirname);
			exit(1);
		}
	}

	free(dirname);
	free(name_tmp);
}

#else

void setup_homedir(void){
        char *dirname;
        char *name_tmp;
        char *envptr;
        size_t strlength = 0;
        size_t reqlength = 0;
        DIR *dirptr;
        FILE *out;
        int ret_val = 0;

	strlength = strlen( getenv("HOME") );
	dirname = (char *)malloc( strlength );
	if(dirname == NULL){
		printf("%s: malloc - %s\n", program_invocation, strerror(errno) );
		printf("failed to allocate memory, exiting!\n");
		exit(1);
	}
	(void)strncpy(dirname, (const char *)getenv("HOME"), strlength );
	strlength += strlen("/.lsbench");
	dirname = (char *)realloc(dirname, strlength);
	(void)strncat(dirname, "/.lsbench", strlen("/.lsbench") );

	dirptr = opendir(dirname);
	if(dirptr == NULL){
		printf("%s: opendir - %s\n", program_invocation, strerror(errno) );
		printf("creating lsbench local dir: %s\n", dirname);
		ret_val = mkdir((const char *)dirname, S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH); //returns 0 for success
		if(ret_val != 0){
			printf("%s: mkdir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create directory %s , exiting!\n");
			exit(1);
		}
	}else{
		if( closedir(dirptr) != 0){
			printf("%s: closedir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close directory %s, exiting!\n", dirname);
			exit(1);
		}

	}

	reqlength = strlength + strlen("/lsbench.conf");
	name_tmp = (char *)malloc( reqlength );
	(void)strncpy(name_tmp, (const char *)dirname, strlength );
	(void)strncat(name_tmp, "/lsbench.conf", strlen("/lsbench.conf") );

	if( out = fopen(name_tmp, "r") ){
		if(fclose(out) != 0){
			printf("%s: fclose - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close file %s , exiting!\n", name_tmp);
			exit(1);
		}
	}else{
		//create it
		if( ( out = fopen( name_tmp, "w" ) ) == NULL ) {
			printf("%s: fopen - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create file %s , exiting!\n", name_tmp);
			exit(1);
		}
		if(fprintf(out, "PORT: 3940\n") < 0 ){
			printf("%s: fprintf - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot write to file %s , exiting!\n", name_tmp);
			exit(1);
		}
		if(fclose(out) != 0){
			printf("%s: fclose - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close file %s , exiting!\n", name_tmp);
			exit(1);
		}
	}	

	strlength += strlen("/cache");
	dirname = (char *)realloc(dirname, strlength);
	(void)strncat(dirname, "/cache", strlen("/cache") );

	dirptr = opendir(dirname);
	if(dirptr == NULL){
		printf("%s: opendir - %s\n", program_invocation, strerror(errno) );
		printf("creating directory: %s\n", dirname);
		ret_val = mkdir((const char *)dirname, S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH); //returns 0 for success
		if(ret_val != 0){
			printf("%s: mkdir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot create directory %s, exiting!\n", dirname);
			exit(1);
		}
	}else{
		//unistd.h
		//int access(const char *path, int amode); //returns 0 for success
		if( closedir(dirptr) != 0){
			printf("%s: closedir - %s\n", program_invocation, strerror(errno) );
			printf("Error: cannot close directory %s, exiting!\n", dirname);
			exit(1);
		}
	}
	free(dirname);
	free(name_tmp);
}
#endif

#ifdef __cplusplus
}
#endif

