#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//Reserve 4MB
#define BUF_SIZE (4 * 1024 * 1024)
//The decryption key!
#define SEED 0x166920ED

//arg1: A pointer containing the address of the file contents after it's been loaded into memory
//arg2: length of the contents in memory
void decrypt(unsigned char *file_ptr, unsigned long fsize)
{
	unsigned long crypted_size = fsize - fsize % 2;
	for (unsigned long i = 2; i < crypted_size; i+=4)
	{
		long j = i-1;
		// j / 3 gets floored here
		if (SEED % j < j / 3)
		{
			//Swap bytes here
			int tmp = file_ptr[i];
			file_ptr[i] = file_ptr[j];
			file_ptr[j] = tmp;
		}
	}
}

int main(int argc, char *argv[]) {

	FILE *fptr;
	FILE *fout;
	unsigned char str_length;
	char OutFileName[255];
	unsigned char *buffer;
	
	if (argc < 2)
	{
		printf("Usage: %s <input file>\n",argv[0]);
		printf("OR     %s <input file> <output file>\n",argv[0]);
		exit(2);
	}
	
	if (argc < 3)
	{
		unsigned char *InFileName = argv[1];
		str_length = strlen(InFileName);
		if (str_length+11 > 255)
		{
			printf("Cannot fit filename, great job genius");
			exit(1);
		}
		
		unsigned char *last_slash = strrchr(InFileName,'.');
		unsigned long lengthWithoutExtension = last_slash-InFileName;
		//printf("%li\n",lengthWithoutExtension);
		//exit(1);
		
		//strncpy(OutFileName,"decrypted_",255);
		strncpy(OutFileName,InFileName,lengthWithoutExtension);
		strncpy(OutFileName+lengthWithoutExtension,"_decrypted.u",255-lengthWithoutExtension);
		//printf("%s\n",OutFileName);
		//exit(0);
		//
		
		
	}
	else
	{
		strcpy(OutFileName, argv[2]);
	}
	
	buffer = (unsigned char *)malloc(BUF_SIZE);
	if(buffer == NULL)
	{
		printf("Cannot alloc %d bytes\n", BUF_SIZE);
		exit(-1);
	}
	
	fptr = fopen(argv[1],"rb");
	if(fptr == NULL)
	{
	  printf("Error opening %s!\n",argv[1]);
	  exit(1);             
	}
	
	//You have to seek to the end to get the file
	//size in C
	fseek(fptr, 0, SEEK_END);
	unsigned long fsize = ftell(fptr);
	fseek(fptr, 0, SEEK_SET);
	
	fread(buffer, fsize, 1, fptr); //Read entire file into memory
	
	decrypt(buffer,fsize);
	
	fout = fopen(OutFileName, "wb");
	
	if(fout == NULL)
	{
	  printf("Error creating output file %s!\n",OutFileName);
	  exit(1);             
	}
	fwrite(buffer,fsize,1,fout);
	
	fclose(fptr);
	fclose(fout);
	
	printf("Succesfully wrote %s\n",OutFileName);
	
	free(buffer);
	
    return 0;
}
