// File: /workspace/github_cpp_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x178, %rsp            # imm = 0x178
leaq 0x68(%rsp), %rcx
movq %rcx, -0x10(%rcx)
xorl %eax, %eax
movq %rax, -0x8(%rcx)
movb $0x0, (%rcx)
movq %rax, 0x140(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x130(%rsp)
movl $0x248, %edi            # imm = 0x248
callq 0x21c0
movq %rax, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
leaq 0x18(%rax), %rdi
movq %rdi, 0x128(%rsp)
callq 0x21f0
movq %rbx, %rax
addq $0x238, %rax            # imm = 0x238
movq %rax, 0x228(%rbx)
movq $0x0, 0x230(%rbx)
movb $0x0, 0x238(%rbx)
leaq 0x130(%rsp), %rsi
movq %rbx, %rdi
callq 0x323c
xorl %r12d, %r12d
leaq 0x80(%rsp), %rax
movl %r12d, -0x8(%rax)
leaq 0x90(%rsp), %rax
movq %rax, -0x10(%rax)
movq %r12, -0x8(%rax)
movb %r12b, (%rax)
leaq 0x108(%rsp), %rax
movl %r12d, -0x8(%rax)
leaq 0x118(%rsp), %rax
movq %rax, -0x10(%rax)
movq %r12, -0x8(%rax)
movb %r12b, (%rax)
leaq 0x48(%rsp), %rax
movq %rax, -0x10(%rax)
movq %r12, -0x8(%rax)
movb %r12b, (%rax)
leaq 0x28(%rsp), %rax
movq %rax, -0x10(%rax)
movq %r12, -0x8(%rax)
movb %r12b, (%rax)
leaq 0x160(%rsp), %rax
movl %r12d, (%rax)
movl %r12d, 0x10(%rax)
leaq 0x148(%rsp), %rax
movl %r12d, (%rax)
movl %r12d, 0x10(%rax)
movq 0x5589(%rip), %r15      # 0x7fe0
movq 0x5572(%rip), %r13      # 0x7fd0
xorl %ebp, %ebp
testl %ebp, %ebp
setne %al
testl %r12d, %r12d
setne %cl
testb %cl, %al
jne 0x2ff1
callq 0x280d
movq %r15, %rdi
leaq 0x14(%rsp), %rsi
callq 0x2120
movq %r15, %rdi
callq 0x22f0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x2280
movl 0x14(%rsp), %eax
decl %eax
cmpl $0x3, %eax
ja 0x2fa4
leaq 0x256c(%rip), %rcx      # 0x5020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x25, %edx
movq %r13, %rdi
leaq 0x262f(%rip), %rsi      # 0x50fb
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movq %r15, %rdi
leaq 0x58(%rsp), %rsi
callq 0x2200
movq %r15, %rdi
callq 0x22f0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x2280
movl $0x20, %edx
movq %r13, %rdi
leaq 0x25f3(%rip), %rsi      # 0x5121
callq 0x21e0
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq %r13, %rdi
callq 0x21e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movl $0x22, %edx
movq %r13, %rdi
leaq 0x25c4(%rip), %rsi      # 0x5142
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
leaq 0xf0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
addq %rsi, %rdx
leaq 0xe0(%rsp), %rdi
callq 0x3d4a
movq 0x128(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x24bc
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0x2c0f
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x21d0
xorl %r14d, %r14d
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
leaq -0x714(%rip), %rdx      # 0x250c
movq %rbx, %rcx
callq 0x22e0
movq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0x21a0
jmp 0x2fe8
movl $0x29, %edx
movq %r13, %rdi
leaq 0x2561(%rip), %rsi      # 0x51a9
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movq %r15, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2200
movq %r15, %rdi
callq 0x22f0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x2280
movl $0xc, %edx
movq %r13, %rdi
leaq 0x2529(%rip), %rsi      # 0x51d3
callq 0x21e0
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq %r13, %rdi
callq 0x21e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
leaq 0xb0(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
addq %rsi, %rdx
leaq 0xa0(%rsp), %rdi
callq 0x3d4a
leaq 0x108(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x2110
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
je 0x2d4f
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x108(%rsp), %rdi
movq 0x110(%rsp), %rsi
movl $0xc70f6907, %edx       # imm = 0xC70F6907
callq 0x2060
movl %eax, 0x100(%rsp)
movl %eax, 0x158(%rsp)
movl $0x1, 0x148(%rsp)
movq %rbx, 0x150(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x39f0
xorl %r14d, %r14d
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
leaq -0x66b(%rip), %rdx      # 0x273d
movq %rbx, %rcx
callq 0x22e0
movq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0x21a0
movl $0x1, %r12d
jmp 0x2fe8
movb $0x1, %r14b
jmp 0x2fe8
movl $0x27, %edx
movq %r13, %rdi
leaq 0x2387(%rip), %rsi      # 0x5165
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movq %r15, %rdi
leaq 0x38(%rsp), %rsi
callq 0x2200
movq %r15, %rdi
callq 0x22f0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
xorl %esi, %esi
callq 0x2280
movl $0xd, %edx
movq %r13, %rdi
leaq 0x234d(%rip), %rsi      # 0x518d
callq 0x21e0
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
movq %r13, %rdi
callq 0x21e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
leaq 0xd0(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
addq %rsi, %rdx
leaq 0xc0(%rsp), %rdi
callq 0x3d4a
leaq 0x80(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x2110
movq 0xc0(%rsp), %rdi
leaq 0xd0(%rsp), %rax
cmpq %rax, %rdi
je 0x2ee5
movq 0xd0(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x80(%rsp), %rdi
movq 0x88(%rsp), %rsi
movl $0xc70f6907, %edx       # imm = 0xC70F6907
callq 0x2060
movl %eax, 0x78(%rsp)
movl $0xd, %edx
movq %r13, %rdi
leaq 0x2289(%rip), %rsi      # 0x519b
callq 0x21e0
movl 0x78(%rsp), %esi
movq %r13, %rdi
callq 0x22b0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movl 0x78(%rsp), %eax
movl %eax, 0x170(%rsp)
movl $0x2, 0x160(%rsp)
movq %rbx, 0x168(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x341c
xorl %r14d, %r14d
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
leaq -0x84c(%rip), %rdx      # 0x273d
movq %rbx, %rcx
callq 0x22e0
movq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0x21a0
movl $0x1, %ebp
jmp 0x2fe8
movl $0x22, %edx
movq %r13, %rdi
leaq 0x222d(%rip), %rsi      # 0x51e0
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
callq 0x280d
xorl %r14d, %r14d
testb %r14b, %r14b
je 0x2a60
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x300d
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x3029
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x108(%rsp), %rdi
leaq 0x118(%rsp), %rax
cmpq %rax, %rdi
je 0x304e
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x3073
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x21d0
leaq 0x130(%rsp), %rdi
callq 0x33b6
movq 0x58(%rsp), %rdi
leaq 0x68(%rsp), %rax
cmpq %rax, %rdi
je 0x309c
movq 0x68(%rsp), %rsi
incq %rsi
callq 0x21d0
xorl %eax, %eax
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movq %rbx, %rdi
callq 0x33b6
movl $0x248, %esi            # imm = 0x248
movq %rbx, %rdi
jmp 0x31c8
movq %rax, %r14
jmp 0x31cd
movq %rax, %r14
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0x314b
movq 0xf0(%rsp), %rsi
jmp 0x313e
jmp 0x3116
movq %rax, %r14
movq 0xc0(%rsp), %rdi
leaq 0xd0(%rsp), %rax
cmpq %rax, %rdi
je 0x314b
movq 0xd0(%rsp), %rsi
jmp 0x313e
movq %rax, %rdi
callq 0x3411
movq %rax, %r14
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
je 0x314b
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x21d0
jmp 0x314b
movq %rax, %r14
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x3167
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x3183
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x108(%rsp), %rdi
leaq 0x118(%rsp), %rax
cmpq %rax, %rdi
je 0x31a8
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x21d0
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0x31cd
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x21d0
leaq 0x130(%rsp), %rdi
callq 0x33b6
movq 0x58(%rsp), %rdi
leaq 0x68(%rsp), %rax
cmpq %rax, %rdi
je 0x31f6
movq 0x68(%rsp), %rsi
incq %rsi
callq 0x21d0
movq %r14, %rdi
callq 0x22c0