#include "globals.h"
#include "sfxformat.h"
#include "Formatter.h"
#include "String.h"
#include "assert.h"
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <errno.h>
#ifndef WINDOWS
#include <unistd.h>
#endif

#define MAX_SUPPORTED_VERSION 1
#define BUFFER_SIZE 4*1024 /*4 kb buffer*/

static bool in_debug_mode = false;

#ifdef WINDOWS
#define LOG(x) if (in_debug_mode) System::WriteLog(x)
#else
#define LOG(x) if (in_debug_mode) printf(x)
#endif

STRING GetExtractorFileName()
{
#ifdef WINDOWS
	
	STRING file_name = (STRING) System::SafeAllocMemory((MAX_PATH + 1) * sizeof(char));
	if ( 0 == file_name)
	{
		return 0;
	}
	GetModuleFileNameA(GetModuleHandleW(NULL),file_name,MAX_PATH);
	return file_name;
#endif
}

bool IsHeaderValid( SFXHeader* header)
{
	if ( 0 != System::MemCmp((BYTE*)SIGNATURE,header->Signature, 19))
	{
		return false;
	}
	else if ( MAX_SUPPORTED_VERSION < header->Version)
	{
		return false;
	}
	else
		return true;
}

STRING CreateTempFolder()
{
	UINT someUniqValue = 0; 
#ifdef WINDOWS
	someUniqValue = GetTickCount();
#else
	someUniqValue = rand();
#endif
	STRING result = (STRING)System::SafeAllocMemory(20);
	if ( 0 == result )
		return 0;
	String::Sprintf2(result,"sfx%u.tmp%s", someUniqValue, (int)PATH_SEPARATOR);
	return result;
}

static BYTE BUFFER[BUFFER_SIZE];

bool CopyFileData(File* source, File* dest, UINT copyAmount)
{
	UINT fileSize = copyAmount;
	while ( fileSize != 0 )
	{
		UINT dataSize = 0;
		dataSize = fileSize < BUFFER_SIZE ? fileSize : BUFFER_SIZE;
		if ( dataSize != source->Read(source,BUFFER,dataSize) )
			return false;

		if ( false == dest->Write(dest,BUFFER,dataSize))
			return false;
		fileSize -= dataSize;
	}

	return true;
}

STRING GetStringById(UINT id, UINT* stringOffsetTable, File* tableHolder)
{
	//get absolute offset of desired string
	UINT absoluteStringOffset = *(stringOffsetTable + id);
	//move file pointer to it
	if ( false == tableHolder->Seek(tableHolder,absoluteStringOffset,SEEK__BEGIN))
		return 0;

	UINT fileNameSize = tableHolder->ReadUINT(tableHolder);
	//get file path
	STRING fileName = (STRING)System::SafeAllocMemory(fileNameSize + 1);
	if ( 0 == fileName)
		return 0;
	if (fileNameSize != tableHolder->Read(tableHolder,(BYTE*)fileName, fileNameSize))
		return 0;

	return fileName;
}

static UINT filesDataStartOffset = 0;
static FileInformation* fileInfoTable = 0;

bool ExtractFile(UINT fileID, FileInformation* fileInfoTable, UINT* stringsOffsetsTable, File* dataHolder, STRING targetFolder )
{
	UINT fileSize = (fileInfoTable + fileID)->Size;
	UINT fileNameId = /*(fileInfoTable + fileID)->NameStringId*/ fileID;
	UINT currentFileDataOffset = filesDataStartOffset;
	if ( false == dataHolder->Seek(dataHolder, filesDataStartOffset, SEEK__BEGIN) )
		return false;
	for ( UINT index = 0; index < fileID; index++)
	{
		currentFileDataOffset+= (fileInfoTable + index)->Size;
	}
	
	STRING fileName = GetStringById(fileNameId, stringsOffsetsTable, dataHolder);
	if ( 0 == fileName )
		return false;

	STRING fileFullPath = Path::Combine(targetFolder, fileName);
	if ( 0 == fileFullPath)
		return false;
	LOG("extracting '");LOG(fileName);LOG("'...");
	if ( Path::IsDirectory(fileFullPath) )
		File::CreateDirectory(fileFullPath);
	else
	{
		//we must be sure, that directory for file exists
		//if not - create it
		STRING fileDirectory = Path::GetFileFolder(fileFullPath);
		if ( fileDirectory == 0){
			LOG("ERROR:failed to find file '");LOG(fileFullPath);LOG("' directory!\n");
			return false;
		}
		File::CreateDirectory(fileDirectory);
		System::SafeFreeMemory(fileDirectory);
		File* targetFile = File::Create(fileFullPath);
		if ( 0 == targetFile)
			return false;
		
		//move file pointer back to file data
		if ( false == dataHolder->Seek(dataHolder,currentFileDataOffset, SEEK__BEGIN))
			return false;
		
		if ( false == CopyFileData(dataHolder, targetFile, fileSize))
			return false;

		targetFile->Close(targetFile);
		System::SafeFreeMemory(targetFile);
	}

	System::SafeFreeMemory(fileName);
	System::SafeFreeMemory(fileFullPath);
	LOG("OK\n");
	return true;
}

bool RemoveFolder ( STRING folderName)
{
#ifdef WINDOWS
	STRING folder = (STRING) System::SafeAllocMemory(String::StrLen(folderName) + 30);//20 actually
	String::StrCpy(folder,"cmd /C rmdir /S /Q ");
	String::StrCat(folder,folderName);
	WinExec(folder, SW_HIDE);
	
	System::SafeFreeMemory(folder);
	return true;
#else
	
	STRING folder = (STRING) System::SafeAllocMemory(strlen(folderName) + 30);//20 actually
	strcpy(folder,"rm -rf ");
	strcat(folder,folderName);
	system(folder);
	System::SafeFreeMemory(folder);
	return true;
#endif

}

int install(STRING extractorFullName){


	if ( 0 == extractorFullName)
	{
		System::ShowErrorMessage("Failed to get extractor name");
		return -1;
	}
	//open self
	LOG("launcher file name ='");LOG(extractorFullName);LOG("'\n");
	File* self = File::Open(extractorFullName);
	if ( 0 == self )
	{
		System::ShowErrorMessage("Failed to open extractor");
		return -1;
	}

	Formatter* formatter = (Formatter*)System::SafeAllocMemory(sizeof(Formatter));
	formatter->_file = self;
	
	SFXFooter* footer = formatter->ParseFooter();
	if ( 0 == footer )
	{
		self->Close(self);
		System::ShowErrorMessage("Failed to navigate to SFX Footer");
		return -1;
	}
	
	if (in_debug_mode ){
		STRING footer_buffer = (STRING)System::SafeAllocMemory(40); //39 should be enough
		String::Sprintf2(footer_buffer,"PackageSize=%u CRC=%u\n", footer->PackageSize, footer->CRC32);
		LOG("SFX Footer record parsed:");LOG(footer_buffer);
	}
	
	//navigate to header
	if ( false == self->Seek(self,-8 - footer->PackageSize, SEEK__END) ){
		self->Close(self);
		LOG("ERROR: Failed to navigate to Header Record!");
		return -1;
	}
	SFXHeader* header = formatter->ParseHeader();

	if ( 0 == header ){
		self->Close(self);
		//delete footer;
		System::ShowErrorMessage("Failed to parse SFX Header");
		LOG("Failed to parse SFX Header\n");
		return -1;
	}
	LOG("SFX Header record parsing...");
	//check header
	if ( ! IsHeaderValid(header) )
	{
		self->Close(self);
		/*delete footer;
		delete header;*/
		System::ShowErrorMessage("SFX Header invalid");
		LOG("FAILED! Header is invalid.\n");
		return -1;
	}
	LOG("OK\n");
	
	LOG("Execution Info parsing...");
	ExecutionInfo* executionInfo = formatter->ParseExecutionInfo();

	if ( 0 == executionInfo)
	{
		self->Close(self);
		/*delete footer;
		delete header;*/
		System::ShowErrorMessage("Failed to parse ExecutionInfo");
		return -1;
	}
	LOG("OK\n");
	
	LOG("File Information Table parsing...");
	fileInfoTable = formatter->ParseFileInformationTable(header->numberOfFiles);

	if ( 0 == fileInfoTable)
	{
		self->Close(self);
		/*delete footer;
		delete header;
		delete executionInfo;*/
		System::ShowErrorMessage("Failed to parse File Information Table");
		return -1;
	}
	LOG("OK\n");

	LOG("Required Files Table parsing...");
	UINT requiredIdsCount = self->ReadUINT(self); //if zero - all content of archive need to be extracted
	UINT* requiredIdsTable = 0;
	if ( 0 != requiredIdsCount)
	{
		//read ids then
		UINT tableSize = requiredIdsCount * 4;
		requiredIdsTable = (UINT*)System::SafeAllocMemory(tableSize);
		if ( 0 == requiredIdsTable  || tableSize != self->Read(self,(BYTE*)requiredIdsTable,tableSize) )
		{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			System::ShowErrorMessage("Failed to parse Reqired Files Table");
			return -1;
		}
	}
	LOG("OK\n");
	
	LOG("Allocating memory for Strings Table...");
	UINT	stringTableOffset = self->GetCurentPos(self);
	UINT	stringTableEntriesCount = header->numberOfFiles + 2;
	UINT*	stringTableOffsetsTable = (UINT*)System::SafeAllocMemory( 4 * (stringTableEntriesCount));
	
	if ( 0 == stringTableOffsetsTable)
	{
		self->Close(self);
		/*delete footer;
		delete header;
		delete executionInfo;*/
		if ( 0 != requiredIdsCount)
			System::SafeFreeMemory( requiredIdsTable);
		System::ShowErrorMessage("Failed to allocate memory for Strings Table");
		return -1;
	}
	LOG("OK\n");
	
	LOG("Parsing Strings Table...");
	UINT skippedBytes = 0;
	//skip string table and build table of strings offsets. it's entries count = numberOfFiles + 2; 1 - for runnable id and 1 for args
	for ( UINT entryIndex = 0; entryIndex < stringTableEntriesCount; entryIndex++)
	{
		*(stringTableOffsetsTable + entryIndex) = stringTableOffset + skippedBytes;
		skippedBytes += 4;
		UINT stringSize = self->ReadUINT(self);
		//skip string
		if ( false == self->Skip(self,stringSize))
		{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to parse Strings Table");
			return -1;
		}
		skippedBytes += stringSize; 
	}
	LOG("OK\n");

	filesDataStartOffset = self->GetCurentPos(self);
	
	LOG("Getting system temporary folder...");
	//now, prepare for extraction
	STRING temporaryFolder = System::GetTemporaryFolder();
	if ( 0 == temporaryFolder )
	{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to get system temporary folder");
			return -1;
	}
	LOG("OK\n");

	LOG("Forming temporary folder...");
	//form extraction folder
	STRING tempFolder = CreateTempFolder();
	if (0 == tempFolder)
	{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to form extraction temporary folder");
			return -1;
	}
	LOG("OK\n");

	LOG("Creating extraction folder...");
	STRING extractionFolder = Path::Combine( temporaryFolder, tempFolder);
	if (0 == extractionFolder)
	{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to combine extraction folder");
			return -1;
	}
	LOG("OK\n");
	//System::SafeFreeMemory(temporaryFolder);
	System::SafeFreeMemory(tempFolder);

	LOG("Extracting required files\n");
	//do we need to extract all files?
	if ( 0 == requiredIdsCount )
	{//extract all
		for ( UINT fileID = 0; fileID < header->numberOfFiles; fileID++)
				if (false == ExtractFile(fileID, fileInfoTable, stringTableOffsetsTable, self, extractionFolder))
				{
					self->Close(self);
					/*delete footer;
					delete header;
					delete executionInfo;*/
					if ( 0 != requiredIdsCount)
						System::SafeFreeMemory( requiredIdsTable);
					System::SafeFreeMemory(stringTableOffsetsTable);
					System::ShowErrorMessage("Failed to extract file(s). Ensure that your temporary folder is accessable and have enough free size.");
					RemoveFolder(extractionFolder);
					return -1;
				}
	}
	else
		for ( UINT reqId = 0; reqId < requiredIdsCount; reqId++ )
		{
			UINT requiredFileId = *(requiredIdsTable + reqId);
			if (false == ExtractFile(requiredFileId, fileInfoTable, stringTableOffsetsTable, self, extractionFolder))
				{
					self->Close(self);
					/*delete footer;
					delete header;
					delete executionInfo;*/
					if ( 0 != requiredIdsCount)
						System::SafeFreeMemory( requiredIdsTable);
					System::SafeFreeMemory(stringTableOffsetsTable);
					System::ShowErrorMessage("Failed to extract file(s). Ensure that your temporary folder is accessable and have enough free size.");
					RemoveFolder(extractionFolder);
					return -1;
				}
		}
	LOG("Extraction succseeded\n");	

	LOG("Reading autorun arguments..."); 
	//get argument string
		STRING tmpArguments = GetStringById(executionInfo->ArgsStringId, stringTableOffsetsTable, self);
		if ( 0 == tmpArguments)
		{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to retreive arguments for executable.");
			RemoveFolder(extractionFolder);
			return -1;
		}
		LOG("OK\n"); 
		LOG("Reading autorun path..."); 
	//prepare it
		STRING arguments = String::ReplaceAll(tmpArguments,ARCHIVE_PATH_PLACE_HOLDER, extractorFullName);
		STRING origExecString = GetStringById(executionInfo->ExecutableStringId, stringTableOffsetsTable, self);
		STRING tmpExecutionString = Path::Combine(extractionFolder, origExecString); //here we leak some memory
		STRING executionString = (STRING)System::SafeAllocMemory(String::StrLen(tmpExecutionString) + 7);

		if ( 0 == executionString)
		{
			self->Close(self);
			/*delete footer;
			delete header;
			delete executionInfo;*/
			if ( 0 != requiredIdsCount)
				System::SafeFreeMemory( requiredIdsTable);
			System::SafeFreeMemory(stringTableOffsetsTable);
			System::ShowErrorMessage("Failed to allocate enough memory to form execution string.");
			RemoveFolder(extractionFolder);
			return -1;
		}
		LOG("OK\n"); 
	UINT flags = executionInfo->Flags;
	if ( (flags & FLAG_JAVA_APP ) == 1)
	//analyze flags - is executable Java class?
		{
			//yes: start JVM then
			
			if ( flags & FLAG_JAVA_WINDOWED_APP )
			{

				String::StrCpy(executionString,"javax");
			//	strcat(executionString, origExecString);
			}
			else 
			{
				String::StrCpy(executionString,"java");
			//	strcat(executionString, origExecString);
			}
			//args here a bit altered
			STRING tmp = (STRING)System::SafeAllocMemory(String::StrLen(arguments) + String::StrLen(origExecString) + 20);
			String::StrCpy(tmp, origExecString);
			String::StrCat(tmp," ");
			String::StrCat(tmp, arguments);
			System::SafeFreeMemory(arguments);
			arguments = tmp;
		}
	else
		//no, native executable
	{
		System::SafeFreeMemory(executionString);
		executionString = tmpExecutionString;
	}
	#ifdef WINDOWS
	bool result = SetCurrentDirectoryA(extractionFolder);
	#else
	chdir(extractionFolder);
	#endif
	LOG("Executing autorun: '");LOG(executionString);LOG("'...");
	//execute what needed and wait for it
	if ( false == System::ExecuteAndWait(executionString, arguments))
	{
		System::ShowErrorMessage("Failed to start executable.");
		RemoveFolder(extractionFolder);
		return -1;
	}
	LOG("OK\n");
	//executable finished - do clean up
	//simply remove recursively extraction directory
	LOG("Removing temporary folder...");
#ifdef WINDOWS
	SetCurrentDirectoryA(temporaryFolder);
#else
	chdir(temporaryFolder);
#endif
	RemoveFolder(extractionFolder);
	LOG("FINISHED\n");
	LOG("All went OK\n");
	//whoo... we done
	return 0;


}

#ifdef WINDOWS
int main()
#else
int main(int argc, char** argv)
#endif
{

	//__asm int 3;
	//get extractor file name
#ifdef WINDOWS
	STRING extractorFullName = GetExtractorFileName();
	STRING commandLine = GetCommandLineA();
	//are we in debug mode?
	in_debug_mode = String::EndsWith(commandLine,"-debug");
#else
	STRING extractorFullName = argv[0];
	if ( argc > 1)
		in_debug_mode = String::EndsWith(argv[1],"-debug");
#endif
	
	if ( in_debug_mode )
	{
#ifdef WINDOWS
		if ( false == System::AllocateConsole("org.eclipse.epp.sfx native launcher debug console"))
		{
			System::ShowErrorMessage("Failed to allocate debug console");
			return -1;
		}
#else
		printf("[DEBUG]org.eclipse.epp.sfx native launcher started\n");
#endif
	}
	int retCode = install(extractorFullName);
	
	if ( in_debug_mode ){
		LOG("In debug mode, press any key to close this window");
		#ifdef WINDOWS
			char buffer;
			DWORD dwDummy;
			ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),&buffer, 1, &dwDummy, NULL );
		#else
			int dummy;
			scnaf("%i", &dummy);
		#endif
	}
}
