// File: LandonSwartz[P]TheGreatEncryptor/main.cpp
// Function: main
int main(int argc, char*argv[])
{
	string filename;
	vector<string> fileContents;

	struct ft * args = new (struct ft);
	if(!args)
	{
		cerr<<"Memory allocation failed!"<<endl;
		exit(1);
	}
	args->fileVector = fileContents;

	hashing HashObj_encrypt;
	hashing HashObj_decrypt;

	// Using one variable for password may be confusing. This has been changed because in one instance,
	// a password is set, and in another, it is entered. Having separate variables should also improve
	// the overall security of the program.
	string password_set;
	string password_entered;

	// Create the base encryption class object
	encryption_base encryptionObj;
	encryption_base decryptionObj;

	pthread_t threads[NUM_THREADS];

	int choice;
	int exitCode = 1;
	int rc;

	int has_encrypted_once = 0;
	int has_decrypted_once = 0;

	//creating threads
	while(exitCode)
	{
		if (has_encrypted_once && has_decrypted_once)
			break;

		printMenu();
		cin>>choice;
		cin.ignore();
		cin.clear();

		switch(choice) {
			case 1:
				//read in file and prove that you've read it in
				//get size of file
				//divide into even chunks
				//send to the threads
				cout<<"What is the name of the file to hash?"<<endl;
				cin>>filename;
				cin.ignore();
				cin.clear();
				cout<<"You choose to read in the file: "<<filename<<endl;
				cout<<"If wrong then please read in again"<<endl;
				args->file.open(filename);
				rc = pthread_create(&threads[0], NULL, readFile, (void *)args);
				pthread_join(threads[0], NULL);
				break;
			case 2: 
				//encrypt file
				
				cout<<"What would you like the password to be?"<<endl;
				cin>>password_set;
				cin.ignore();
				cin.clear();
				cout<<"You entered: "<< password_set <<endl;
				HashObj_encrypt.set_password(password_set);
				HashObj_encrypt.set_hash_key_from_password();

				cout<<"Hash key is: "<<HashObj_encrypt.get_hash_key()<<endl;
				
				// Once the password has been retrieved, set the hash key in the encryption object
				encryptionObj.set_hash_key(HashObj_encrypt.get_hash_key());

				// The encryption class is ready to do some encryption. Give the class the data to work with.
				// Data being sent to this function should not already be encrypted.
				encryptionObj.set_decrypted_data(&(args->fileVector));

				// Call the getter function on the encryption object. Even if the data is not retrieved, calling
				// the getter function will perform the actual encryption. (This technically returns the address
				// of the agrs->fileVector retrieved earlier, but we already have it.)
				encryptionObj.get_encrypted_data();

				// Landon & Rushil, the data is modified in the vector, now what function do I call to update the file??
				/* 
				Call function here to update file based on the now modified vector
				*/
				rc = pthread_create(&threads[0], NULL, newFile, (void*)args);

				has_encrypted_once = 1;

				pthread_join(threads[0], NULL);
				
				break;
			case 3:
				//decrypt file

				cout << "Enter your password to decrypt the file: " << endl;
				cin >> password_entered;
				cin.ignore();
				cin.clear();
				cout << "You entered:" << password_entered << endl;
				HashObj_decrypt.set_password(password_entered);
				HashObj_decrypt.set_hash_key_from_password();

				// Set the hash key in the decryption object.
				decryptionObj.set_hash_key(HashObj_decrypt.get_hash_key());

				// Set the data based on what is stored in the file.
				decryptionObj.set_encrypted_data(&(args->fileVector));

				// Call the getter function to ensure the decryption happens.
				decryptionObj.get_decrypted_data();

				// Call the function necessary to overwrite the data in the file based on modifications made
				// to the vector which contains the file contents.
				rc = pthread_create(&threads[0], NULL, newFile, (void*)args);

				has_decrypted_once = 1;

				pthread_join(threads[0], NULL);
				break;
			case 4:
				//exit program
				exitCode = 0;
				break;
			default:
				//wrong choice
				cout<<"Please choose a choice between 1-4"<<endl;
				printMenu();
				break;
		}
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2230
leaq -0x48(%rbp), %rdi
callq 0x33d0
movl $0x248, %edi            # imm = 0x248
callq 0x2190
movq %rax, -0x1a8(%rbp)
jmp 0x29fe
movq -0x1a8(%rbp), %rdi
callq 0x33f0
jmp 0x2a0c
movq -0x1a8(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0x2a8c
movq 0x95cb(%rip), %rdi      # 0xbff0
leaq 0x56b3(%rip), %rsi      # 0x80df
callq 0x2180
movq %rax, -0x1b0(%rbp)
jmp 0x2a3a
movq -0x1b0(%rbp), %rdi
movq 0x9570(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2a4f
movl $0x1, %edi
callq 0x21e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x31bf
movq -0x1a8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x248, %esi            # imm = 0x248
callq 0x21a0
jmp 0x31bf
movq -0x50(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3440
jmp 0x2a9b
leaq -0x88(%rbp), %rdi
callq 0x3690
leaq -0xb0(%rbp), %rdi
callq 0x3690
leaq -0xd0(%rbp), %rdi
callq 0x2230
leaq -0xf0(%rbp), %rdi
callq 0x2230
leaq -0x108(%rbp), %rdi
callq 0x36c0
leaq -0x120(%rbp), %rdi
callq 0x36c0
movl $0x1, -0x130(%rbp)
movl $0x0, -0x138(%rbp)
movl $0x0, -0x13c(%rbp)
cmpl $0x0, -0x130(%rbp)
je 0x313a
cmpl $0x0, -0x138(%rbp)
je 0x2b25
cmpl $0x0, -0x13c(%rbp)
je 0x2b25
jmp 0x313a
callq 0x2910
jmp 0x2b2c
movq 0x94a5(%rip), %rdi      # 0xbfd8
leaq -0x12c(%rbp), %rsi
callq 0x2110
jmp 0x2b41
movq 0x9490(%rip), %rdi      # 0xbfd8
callq 0x2320
jmp 0x2b4f
movq 0x9482(%rip), %rdi      # 0xbfd8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
xorl %esi, %esi
callq 0x22b0
jmp 0x2b69
movl -0x12c(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x1b8(%rbp)
subl $0x3, %eax
ja 0x30fb
movq -0x1b8(%rbp), %rax
leaq 0x5473(%rip), %rcx      # 0x8004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x318f
movq 0x9416(%rip), %rdi      # 0xbfc8
leaq 0x5540(%rip), %rsi      # 0x80f9
callq 0x2180
movq %rax, -0x1c0(%rbp)
jmp 0x2bc7
movq -0x1c0(%rbp), %rdi
movq 0x93e3(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2bdc
movq 0x93f5(%rip), %rdi      # 0xbfd8
leaq -0x30(%rbp), %rsi
callq 0x2200
jmp 0x2bee
movq 0x93e3(%rip), %rdi      # 0xbfd8
callq 0x2320
jmp 0x2bfc
movq 0x93d5(%rip), %rdi      # 0xbfd8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
xorl %esi, %esi
callq 0x22b0
jmp 0x2c16
movq 0x93ab(%rip), %rdi      # 0xbfc8
leaq 0x54fb(%rip), %rsi      # 0x811f
callq 0x2180
movq %rax, -0x1c8(%rbp)
jmp 0x2c32
movq -0x1c8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2160
movq %rax, -0x1d0(%rbp)
jmp 0x2c4b
movq -0x1d0(%rbp), %rdi
movq 0x935f(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2c60
movq 0x9361(%rip), %rdi      # 0xbfc8
leaq 0x54d2(%rip), %rsi      # 0x8140
callq 0x2180
movq %rax, -0x1d8(%rbp)
jmp 0x2c7c
movq -0x1d8(%rbp), %rdi
movq 0x932e(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2c91
movq -0x50(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x1e0(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x20c0
jmp 0x2cb2
movq -0x1e0(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x2510
jmp 0x2cc7
leaq -0x160(%rbp), %rdi
callq 0x2120
movq -0x50(%rbp), %rcx
leaq -0x71e(%rip), %rdx      # 0x25c0
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x1e8(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x2310
movq -0x1e8(%rbp), %rsi
movl %eax, -0x134(%rbp)
movq -0x128(%rbp), %rdi
callq 0x2170
jmp 0x2d10
jmp 0x3135
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x2120
jmp 0x318f
movq 0x928f(%rip), %rdi      # 0xbfc8
leaq 0x5423(%rip), %rsi      # 0x8163
callq 0x2180
movq %rax, -0x1f0(%rbp)
jmp 0x2d4e
movq -0x1f0(%rbp), %rdi
movq 0x925c(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2d63
movq 0x926e(%rip), %rdi      # 0xbfd8
leaq -0xd0(%rbp), %rsi
callq 0x2200
jmp 0x2d78
movq 0x9259(%rip), %rdi      # 0xbfd8
callq 0x2320
jmp 0x2d86
movq 0x924b(%rip), %rdi      # 0xbfd8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
xorl %esi, %esi
callq 0x22b0
jmp 0x2da0
movq 0x9221(%rip), %rdi      # 0xbfc8
leaq 0x53dd(%rip), %rsi      # 0x818b
callq 0x2180
movq %rax, -0x1f8(%rbp)
jmp 0x2dbc
movq -0x1f8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x2160
movq %rax, -0x200(%rbp)
jmp 0x2dd8
movq -0x200(%rbp), %rdi
movq 0x91d2(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2ded
leaq -0x180(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x20c0
jmp 0x2e02
leaq -0x88(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x36e0
jmp 0x2e17
leaq -0x180(%rbp), %rdi
callq 0x2120
leaq -0x88(%rbp), %rdi
callq 0x3710
jmp 0x2e31
movq 0x9190(%rip), %rdi      # 0xbfc8
leaq 0x535a(%rip), %rsi      # 0x8199
callq 0x2180
movq %rax, -0x208(%rbp)
jmp 0x2e4d
leaq -0x88(%rbp), %rdi
callq 0x3740
movl %eax, -0x20c(%rbp)
jmp 0x2e61
movl -0x20c(%rbp), %esi
movq -0x208(%rbp), %rdi
callq 0x22f0
movq %rax, -0x218(%rbp)
jmp 0x2e7c
movq -0x218(%rbp), %rdi
movq 0x912e(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2e91
leaq -0x88(%rbp), %rdi
callq 0x3740
movl %eax, -0x21c(%rbp)
jmp 0x2ea5
movl -0x21c(%rbp), %esi
leaq -0x108(%rbp), %rdi
callq 0x3750
jmp 0x2eb9
movq -0x50(%rbp), %rsi
leaq -0x108(%rbp), %rdi
callq 0x3770
jmp 0x2ecb
leaq -0x108(%rbp), %rdi
callq 0x3790
jmp 0x2ed9
movq -0x50(%rbp), %rcx
leaq -0x6e4(%rip), %rdx      # 0x2800
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x228(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x2310
movq -0x228(%rbp), %rsi
movl %eax, -0x134(%rbp)
movl $0x1, -0x138(%rbp)
movq -0x128(%rbp), %rdi
callq 0x2170
jmp 0x2f20
jmp 0x3135
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x2120
jmp 0x318f
movq 0x907f(%rip), %rdi      # 0xbfc8
leaq 0x5257(%rip), %rsi      # 0x81a7
callq 0x2180
movq %rax, -0x230(%rbp)
jmp 0x2f5e
movq -0x230(%rbp), %rdi
movq 0x904c(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2f73
movq 0x905e(%rip), %rdi      # 0xbfd8
leaq -0xf0(%rbp), %rsi
callq 0x2200
jmp 0x2f88
movq 0x9049(%rip), %rdi      # 0xbfd8
callq 0x2320
jmp 0x2f96
movq 0x903b(%rip), %rdi      # 0xbfd8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
xorl %esi, %esi
callq 0x22b0
jmp 0x2fb0
movq 0x9011(%rip), %rdi      # 0xbfc8
leaq 0x5213(%rip), %rsi      # 0x81d1
callq 0x2180
movq %rax, -0x238(%rbp)
jmp 0x2fcc
movq -0x238(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x2160
movq %rax, -0x240(%rbp)
jmp 0x2fe8
movq -0x240(%rbp), %rdi
movq 0x8fc2(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x2ffd
leaq -0x1a0(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x20c0
jmp 0x3012
leaq -0xb0(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x36e0
jmp 0x3027
leaq -0x1a0(%rbp), %rdi
callq 0x2120
leaq -0xb0(%rbp), %rdi
callq 0x3710
jmp 0x3041
leaq -0xb0(%rbp), %rdi
callq 0x3740
movl %eax, -0x244(%rbp)
jmp 0x3055
movl -0x244(%rbp), %esi
leaq -0x120(%rbp), %rdi
callq 0x3750
jmp 0x3069
movq -0x50(%rbp), %rsi
leaq -0x120(%rbp), %rdi
callq 0x3800
jmp 0x307b
leaq -0x120(%rbp), %rdi
callq 0x3820
jmp 0x3089
movq -0x50(%rbp), %rcx
leaq -0x894(%rip), %rdx      # 0x2800
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x250(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x2310
movq -0x250(%rbp), %rsi
movl %eax, -0x134(%rbp)
movl $0x1, -0x13c(%rbp)
movq -0x128(%rbp), %rdi
callq 0x2170
jmp 0x30d0
jmp 0x3135
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x2120
jmp 0x318f
movl $0x0, -0x130(%rbp)
jmp 0x3135
movq 0x8ec6(%rip), %rdi      # 0xbfc8
leaq 0x50d5(%rip), %rsi      # 0x81de
callq 0x2180
movq %rax, -0x258(%rbp)
jmp 0x3117
movq -0x258(%rbp), %rdi
movq 0x8e93(%rip), %rsi      # 0xbfb8
callq 0x21b0
jmp 0x312c
callq 0x2910
jmp 0x3133
jmp 0x3135
jmp 0x2b01
movl $0x0, -0x4(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x2120
leaq -0xd0(%rbp), %rdi
callq 0x2120
leaq -0xb0(%rbp), %rdi
callq 0x3890
leaq -0x88(%rbp), %rdi
callq 0x3890
leaq -0x48(%rbp), %rdi
callq 0x38b0
leaq -0x30(%rbp), %rdi
callq 0x2120
movl -0x4(%rbp), %eax
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
leaq -0xf0(%rbp), %rdi
callq 0x2120
leaq -0xd0(%rbp), %rdi
callq 0x2120
leaq -0xb0(%rbp), %rdi
callq 0x3890
leaq -0x88(%rbp), %rdi
callq 0x3890
leaq -0x48(%rbp), %rdi
callq 0x38b0
leaq -0x30(%rbp), %rdi
callq 0x2120
movq -0x58(%rbp), %rdi
callq 0x2300
nopw (%rax,%rax)