#include "utility.h"
#include <stdio.h>

//int main() {
//
//	//// Information about CPU
//	//string CPUName = getCPUModel();
//	//string osname = getOSName();
//
//	//printf("OSName : %s\n", osname.c_str());
//	//printf("CPUName : %s\n", CPUName.c_str());
//	//printf("Total memory : %.2f GB\n", getTotalMemoryInGB());
//
//	//if ( meetCUDARequirement() == -1 ) {
//	//	printf("You should update your CUDA driver to version 2.3 or higher\n");
//	//	return 0;
//	//}
//	//
//	//// Information about GPU
//	//DeviceProperties devProperties;
//	//if ( devProperties.getDeviceCount() == 0 ) {
//	//	printf("No avalaible CUDA device.\n");
//	//}
//	//else {
//	//	printf("\n");
//	//	for ( int i = 0; i < devProperties.getDeviceCount(); i++ ) {
//	//		devProperties.printDevProp(i);
//	//	}
//	//}
//
//	BOOST_CPU("filenamelist.txt", 30, "Test");
//
//	system("pause");
//	return 0;
//}

void printUsage() {
	printf("Usage is -l listFile -m workmode -p testmode -o outputPrefix\n");
	printf("\t-i Input List File\n");
	printf("\t-wm work mode (default : CPU)\n");
	printf("\t\tCPU -- CPU mode\n"); 
	printf("\t\tGPU -- GPU mode\n");
	printf("\t-pt Pre-filtering Threshold (default : 99999)\n");
	printf("\t-sm screen mode (default : SCREENING_KSA)\n");
	printf("\t\tSCREENING_KSA -- KSA Approximation in screening step\n"); 
	printf("\t\tSCREENING_CHISQUARE -- Chisquare in screening step\n");
	printf("\t-st Screen Threshold (default : 30.0)\n");
	printf("\t-tm test mode (default : EXACT_GUESS)\n");
	printf("\t\tEXACT_GUESS -- Exact guess for log-linear\n"); 
	printf("\t\tMODEL_SELECTION -- Model selection\n");
	printf("\t-tt Test Threshold\n");
	printf("\t\tDefault : 30.0 for EXCESS_GUESS\n"); 
	printf("\t\tFixed :	10.828 for MODEL_SELECTION\n");
	printf("\t-o Output files' prefixs (default : "")\n");
	printf("Examples : \n");
	printf("\tGBOOST -i .\\filenameList.txt -wm CPU -o output\n\n");
	printf("\tThe program will output three file \n\t\t'OutputDistrCollection.txt' \n\t\t'OutputInteraction.txt'\n\t\t'OutputMarginalAssociation.txt'\n");
}

int main(int argc, char **argv) {
	char* inputListFile = NULL;
	bool validInptFile = false;

	int workMode = CPU_MODE;
	bool validWorkMode = false;

	float prefilteringThreshold = DEFAULT_PREFILTERING_VALUE;
	bool validPrefilteringThreshold = false;

	int screenMode = SCREENING_KSA;
	bool validScreeningMode = false;

	int testMode = EXACT_GUESS;
	bool validTestMode = false;

	float screenThreshold = 30.0;
	bool validScreenThreshold = false;

	float testThreshold = 30.0;
	bool validTestThreshold = false;

	char* outputPrefix = "temp";

	printf("\n");

	//char* inputListFile = "filenamelist.txt";
	//return BOOST_GPU(inputListFile, threshold, outputPrefix, testMode);
	
	// necessary parameters
	for (int i = 1; i < argc; i++) { 
		if (i + 1 != argc) // Check that we haven't finished parsing already
		{
			// Check for input list file
			if ( strcmp(argv[i],"-i") == 0 ) {
				if ( i+1 != argc ) {
					inputListFile = argv[i+1];
					if ( fopen(inputListFile,"r+") != NULL ) {
						validInptFile = true;
					}
					else {
						printf("Unable to open the file : %s\n\n", inputListFile);
					}
				}
				else {
					printf("No input file\n\n");
				}
			}
		}
	}

	if ( !validInptFile ) {
		printUsage();
		//system("pause");
		exit(0);
	}

	// Parse optional arguments, Skip the first argument which is the program name
	for (int i = 1; i < argc; i++) { 
		if (i + 1 != argc) // Check that we haven't finished parsing already
		{
			// Check for workmode
			if ( strcmp(argv[i],"-wm") == 0 ) {
				if ( i+1 != argc ) {
					toUpperCaseString(argv[i+1], strlen(argv[i+1]));
					char* mode = argv[i+1];
				
					if ( strcmp(mode,"CPU") == 0 ) {
						workMode = CPU_MODE;
						validWorkMode = true;
					}
					else if ( strcmp(mode,"GPU") == 0 ) {
						workMode = GPU_MODE;
						validWorkMode = true;
					}
				}
				if ( !validWorkMode ) {
					printf("Unable to parse the work mode. Use CPU mode as default work mode.\n\n");				
				}
			}

			// Parse the pre-filering threshold value
			if ( strcmp(argv[i],"-pt") == 0 ) {
				if ( i+1 != argc ) {
					if(EOF == sscanf(argv[i + 1], "%f", &prefilteringThreshold))
					{
						// parse error 
					}
					else {
						validPrefilteringThreshold = true;
					}
				}

				if ( !validPrefilteringThreshold ) {
					printf("Unable to parse prefiltering threshold value. Using %f as the default prefiltering threshold value\n\n", prefilteringThreshold);
				}
			}

			// Check for screen mode
			if ( strcmp(argv[i],"-sm") == 0 ) {
				if ( i+1 != argc ) {
					toUpperCaseString(argv[i+1], strlen(argv[i+1]));
					char* mode = argv[i+1];

					if ( strcmp(mode,"SCREENING_KSA") == 0 ) {
						screenMode = SCREENING_KSA;
						validScreeningMode = true;
					}
					else if ( strcmp(mode,"SCREENING_CHISQUARE") == 0 ) {
						screenMode = SCREENING_CHISQUARE;
						validScreeningMode = true;
					}
				}
				if ( !validWorkMode ) {
					printf("Unable to parse the screen mode. Use SCREENING_KSA screen mode as default test mode.\n\n");				
				}
			}

			// Check for testmode
			if ( strcmp(argv[i],"-tm") == 0 ) {
				if ( i+1 != argc ) {
					toUpperCaseString(argv[i+1], strlen(argv[i+1]));
					char* mode = argv[i+1];

					if ( strcmp(mode,"EXACT_GUESS") == 0 ) {
						testMode = EXACT_GUESS;
						validTestMode = true;
					}
					else if ( strcmp(mode,"MODEL_SELECTION") == 0 ) {
						testMode = MODEL_SELECTION;
						validTestMode = true;
					}
				}
				if ( !validWorkMode ) {
					printf("Unable to parse the test mode. Use EXACT_GUESS test mode as default test mode.\n\n");				
				}
			}

			// Parse the screen threshold value
			if ( strcmp(argv[i],"-st") == 0 ) {
				if ( i+1 != argc ) {
					if(EOF == sscanf(argv[i + 1], "%f", &screenThreshold))
					{
						// parse error 
					}
					else {
						validScreenThreshold = true;
					}
				}

				if ( !validScreenThreshold ) {
					printf("Unable to parse screen threshold value. Using %f as the default screen threshold value\n\n", screenThreshold);
				}
			} 

			// Parse the test threshold value
			if ( strcmp(argv[i],"-tt") == 0 ) {
				if ( i+1 != argc ) {
					if(EOF == sscanf(argv[i + 1], "%f", &testThreshold))
					{
						// parse error 
					}
					else {
						validTestThreshold = true;
					}
				}
				
				if ( !validTestThreshold ) {
					printf("Unable to parse test threshold value. Using %f as the default test threshold value\n\n", testThreshold);
				}
			} 
			
			// Parse output prefix
			if (strcmp(argv[i],"-o") == 0 ) {
				if ( i+1 != argc ) {
					outputPrefix = argv[i+1];
				}
				else {
					printf("Unable to parse outputPrefix. Outputs files without prefixs.\n\n");
				}
			}
		}
	}

	// Check if GPU avaliable
	if ( workMode == GPU_MODE ) {
		if ( meetCUDARequirement() == -1 ) {
			printf("You should update your CUDA driver to version 2.3 or higher\n");
			//system("pause");
			exit(0);
		}
	}

	//char* inputListFile="./filenamelist.txt";
	//float screenThreshold = 30.0f;
	//float testThreshold = 30.0f;
	//char* outputPrefix = "out_";
	//int testMode = EXACT_GUESS;
	//int screenMode = SCREENING_CHISQUARE;
	//int workMode = CPU_MODE;
	//float prefilteringThreshold = 0.5f;

	printf("Input List File : %s\n", inputListFile);
	printf("Work mode : %s\n", workMode == CPU_MODE ? "CPU" : "GPU");
	printf("Prefiltering threshold : %f\n", prefilteringThreshold);
	printf("Screen mode : %s\n", screenMode == SCREENING_KSA ? "SCREENING_KSA" : "SCREENING_CHISQUARE");
	printf("Screen Threshold : %f\n", screenThreshold);
	printf("Test mode : %s\n", testMode == EXACT_GUESS ? "EXCAT_GUESS" : "MODEL_SELECTION");
	printf("Test Threshold : %f\n", testThreshold);
	printf("Output Prefix : %s\n\n", outputPrefix);

	FLUSH_STDOUT();

	// CPU MODE
	if ( workMode == CPU_MODE ) {
		return BOOST_CPU(inputListFile, outputPrefix, prefilteringThreshold, screenMode, screenThreshold, testMode, testThreshold);
	}
	// GPU MODE
	else {
		return BOOST_GPU(inputListFile, outputPrefix, prefilteringThreshold, screenMode, screenThreshold, testMode, testThreshold);
	}
}