// File: luigix25[P]SSLP/library/SendReceiveFile.cpp
// Function: ReceiveFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, NetSocket&, PublicKey&, bool)
bool ReceiveFile(string & path, string& filename, NetSocket & senderSocket,PublicKey &key,bool progressBar){

	//handle get
	if(filename.size() == 0)
		return false;


	path += filename;
	cout<<"[LOG] File Path: "<<path<<endl;

	uint32_t file_size;
	uint32_t completeFileSize;
	if(!recvIntHMAC(senderSocket,(int32_t&)file_size)) return false;

	if(file_size == 0){				//file non esistente
		cout<<"[LOG] File does not exist or too big"<<endl;
		return true;
	}

	completeFileSize = file_size;

	char *recvd_data;
	int len = 0;
	file_status status;

	cout<<"[LOG] File Size: "<<file_size<<endl;
	WriteFileManager fm(path,file_size);
	DecryptManager dm;
	RSAVerifyManager verify(key);


	struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

    float currentPercentage = 0;
    uint32_t receivedBytes = 0;
    float percentageStep = 100.0f / w.ws_col;
    float lastPercentage = 0.0f;

    while(true){

		recvd_data = recvDataHMAC(senderSocket,len);
		
		if(recvd_data == NULL){
			cout << "recvd_data NULL" <<endl;
			fm.finalize(true);
			return false;
		} 

		EncryptedChunk ec;
		ec.size  = len;
		ec.setCipherText(recvd_data);

		Chunk c;

		if(!dm.DecryptUpdate(c,ec)){
			cout<<"DecryptUpdate error"<<endl;
			fm.finalize(true);
			return false;		
		}

		file_size-= (c.size);


		if(file_size < AES_BLOCK){			//ultimo chunk

			if(!dm.DecryptFinal(c)){
				cout<<"DecryptFinal error"<<endl;
				fm.finalize(true);
				return false;
			}

		}

		receivedBytes += c.size;

		currentPercentage = (double)receivedBytes/(double)completeFileSize * 100;

		if(progressBar){

			while(lastPercentage + percentageStep < currentPercentage){
				cout << "\u25A0"<<flush;
				lastPercentage+=percentageStep;
			}

			/*int col,row;
			cout << "\033[" << col << ";" << row << "H";*/

			if(currentPercentage  >= 100){
				cout << endl;
			}
		}

		if(!verify.RSAUpdate(ec)){
			cout<<"[ERROR]"<<endl;
			fm.finalize(true);


			return false;
		}	

		status = fm.write(c);

		if(status == END_OF_FILE){
			cout<<"[LOG] Transfer Completed"<<endl;
			break;
		} else if(status == FILE_ERROR){
			cout << "FILE_ERROR" << endl;
			fm.finalize(true);
			return false;
		}
	}

	len = 0;
	char *recvd_digest = recvDataHMAC(senderSocket,len);	

	int result;
	result = verify.RSAFinal(recvd_digest);

	if(result != 1){
		fm.finalize(true);						//error
		cout<<"[ERROR] File Verification"<<endl;
		delete[] recvd_digest;
		return false;
	} else {
		cout<<"[LOG] File Verification OK"<<endl;
		fm.finalize(false);
	}
	
	delete[] recvd_digest;

	return true;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3e0, %rsp            # imm = 0x3E0
movb %r8b, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
andb $0x1, %al
movb %al, -0x29(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4350
cmpq $0x0, %rax
jne 0xbc8b
movb $0x0, -0x1(%rbp)
jmp 0xc43f
movq -0x18(%rbp), %rsi
movq -0x10(%rbp), %rdi
callq 0x46c0
movq 0x7319(%rip), %rdi      # 0x12fb8
leaq 0x2a5b(%rip), %rsi      # 0xe701
callq 0x44a0
movq %rax, %rdi
movq -0x10(%rbp), %rsi
callq 0x4470
movq %rax, %rdi
movq 0x72e7(%rip), %rsi      # 0x12fa8
callq 0x4500
movq -0x20(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x85b0
testb $0x1, %al
jne 0xbce0
movb $0x0, -0x1(%rbp)
jmp 0xc43f
cmpl $0x0, -0x30(%rbp)
jne 0xbd11
movq 0x72cb(%rip), %rdi      # 0x12fb8
leaq 0x2a1f(%rip), %rsi      # 0xe713
callq 0x44a0
movq %rax, %rdi
movq 0x72a5(%rip), %rsi      # 0x12fa8
callq 0x4500
movb $0x1, -0x1(%rbp)
jmp 0xc43f
movl -0x30(%rbp), %eax
movl %eax, -0x34(%rbp)
movl $0x0, -0x44(%rbp)
movq 0x7293(%rip), %rdi      # 0x12fb8
leaq 0x2a0c(%rip), %rsi      # 0xe738
callq 0x44a0
movq %rax, %rdi
movl -0x30(%rbp), %esi
callq 0x4720
movq %rax, %rdi
movq 0x7262(%rip), %rsi      # 0x12fa8
callq 0x4500
movq -0x10(%rbp), %rsi
movl -0x30(%rbp), %eax
movl %eax, %edx
leaq -0x2b0(%rbp), %rdi
callq 0x9af0
leaq -0x2b8(%rbp), %rdi
callq 0xa600
jmp 0xbd6e
movq -0x28(%rbp), %rsi
leaq -0x2e0(%rbp), %rdi
callq 0xada0
jmp 0xbd80
movl $0x1, %edi
movl $0x5413, %esi           # imm = 0x5413
leaq -0x2e8(%rbp), %rdx
movb $0x0, %al
callq 0x4790
xorps %xmm0, %xmm0
movss %xmm0, -0x2ec(%rbp)
movl $0x0, -0x2f0(%rbp)
movzwl -0x2e6(%rbp), %eax
cvtsi2ss %eax, %xmm1
movss 0x28b8(%rip), %xmm0     # 0xe678
divss %xmm1, %xmm0
movss %xmm0, -0x2f4(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x2f8(%rbp)
jmp 0xbdd9
movq -0x20(%rbp), %rdi
leaq -0x44(%rbp), %rsi
callq 0x88c0
movq %rax, -0x348(%rbp)
jmp 0xbdef
movq -0x348(%rbp), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0xbea1
movq 0x71ac(%rip), %rdi      # 0x12fb8
leaq 0x2937(%rip), %rsi      # 0xe74a
callq 0x44a0
movq %rax, -0x350(%rbp)
jmp 0xbe21
movq -0x350(%rbp), %rdi
movq 0x7179(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xbe36
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xbe49
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc3f3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2c0(%rbp)
movl %eax, -0x2c4(%rbp)
jmp 0xc431
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2c0(%rbp)
movl %eax, -0x2c4(%rbp)
jmp 0xc425
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2c0(%rbp)
movl %eax, -0x2c4(%rbp)
jmp 0xc419
leaq -0x318(%rbp), %rdi
callq 0xd860
jmp 0xbeaf
movl -0x44(%rbp), %eax
movl %eax, -0x308(%rbp)
movq -0x40(%rbp), %rsi
leaq -0x318(%rbp), %rdi
callq 0xd930
jmp 0xbeca
leaq -0x330(%rbp), %rdi
callq 0xd6b0
jmp 0xbed8
leaq -0x2b8(%rbp), %rdi
leaq -0x330(%rbp), %rsi
leaq -0x318(%rbp), %rdx
callq 0xa700
movb %al, -0x351(%rbp)
jmp 0xbefa
movb -0x351(%rbp), %al
testb $0x1, %al
jne 0xbf9b
jmp 0xbf0a
movq 0x70a7(%rip), %rdi      # 0x12fb8
leaq 0x2842(%rip), %rsi      # 0xe75a
callq 0x44a0
movq %rax, -0x360(%rbp)
jmp 0xbf26
movq -0x360(%rbp), %rdi
movq 0x7074(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xbf3b
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xbf4e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc263
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2c0(%rbp)
movl %eax, -0x2c4(%rbp)
jmp 0xc2a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2c0(%rbp)
movl %eax, -0x2c4(%rbp)
leaq -0x330(%rbp), %rdi
callq 0xd6d0
jmp 0xc2a2
movl -0x320(%rbp), %ecx
movl -0x30(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x30(%rbp)
cmpl $0x10, -0x30(%rbp)
jae 0xc033
leaq -0x2b8(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0xa8c0
movb %al, -0x361(%rbp)
jmp 0xbfce
movb -0x361(%rbp), %al
testb $0x1, %al
jne 0xc031
jmp 0xbfda
movq 0x6fd7(%rip), %rdi      # 0x12fb8
leaq 0x2786(%rip), %rsi      # 0xe76e
callq 0x44a0
movq %rax, -0x370(%rbp)
jmp 0xbff6
movq -0x370(%rbp), %rdi
movq 0x6fa4(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc00b
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xc01e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc263
jmp 0xc033
movl -0x320(%rbp), %ecx
movl -0x2f0(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x2f0(%rbp)
movl -0x2f0(%rbp), %eax
cvtsi2sd %rax, %xmm0
movl -0x34(%rbp), %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd 0x261a(%rip), %xmm1     # 0xe680
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x2ec(%rbp)
testb $0x1, -0x29(%rbp)
je 0xc118
jmp 0xc082
movss -0x2f8(%rbp), %xmm1
addss -0x2f4(%rbp), %xmm1
movss -0x2ec(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xc0ea
movq 0x6f12(%rip), %rdi      # 0x12fb8
leaq 0x263e(%rip), %rsi      # 0xe6eb
callq 0x44a0
movq %rax, -0x378(%rbp)
jmp 0xc0bb
movq -0x378(%rbp), %rdi
movq 0x6ef7(%rip), %rsi      # 0x12fc0
callq 0x4500
jmp 0xc0d0
movss -0x2f4(%rbp), %xmm0
addss -0x2f8(%rbp), %xmm0
movss %xmm0, -0x2f8(%rbp)
jmp 0xc082
movss -0x2ec(%rbp), %xmm0
movss 0x257e(%rip), %xmm1     # 0xe678
ucomiss %xmm1, %xmm0
jb 0xc116
movq 0x6eb2(%rip), %rdi      # 0x12fb8
movq 0x6e9b(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc114
jmp 0xc116
jmp 0xc118
leaq -0x2e0(%rbp), %rdi
leaq -0x318(%rbp), %rsi
callq 0xae30
movb %al, -0x379(%rbp)
jmp 0xc133
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0xc196
jmp 0xc13f
movq 0x6e72(%rip), %rdi      # 0x12fb8
leaq 0x2596(%rip), %rsi      # 0xe6e3
callq 0x44a0
movq %rax, -0x388(%rbp)
jmp 0xc15b
movq -0x388(%rbp), %rdi
movq 0x6e3f(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc170
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xc183
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc263
leaq -0x2b0(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0x9d70
movl %eax, -0x38c(%rbp)
jmp 0xc1b1
movl -0x38c(%rbp), %eax
movl %eax, -0x48(%rbp)
cmpl $0x3, -0x48(%rbp)
jne 0xc1fd
movq 0x6df1(%rip), %rdi      # 0x12fb8
leaq 0x25b3(%rip), %rsi      # 0xe781
callq 0x44a0
movq %rax, -0x398(%rbp)
jmp 0xc1dc
movq -0x398(%rbp), %rdi
movq 0x6dbe(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc1f1
movl $0x3, -0x2fc(%rbp)
jmp 0xc263
cmpl $0x2, -0x48(%rbp)
jne 0xc257
movq 0x6dae(%rip), %rdi      # 0x12fb8
leaq 0x2589(%rip), %rsi      # 0xe79a
callq 0x44a0
movq %rax, -0x3a0(%rbp)
jmp 0xc21f
movq -0x3a0(%rbp), %rdi
movq 0x6d7b(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc234
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xc247
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc263
jmp 0xc259
movl $0x0, -0x2fc(%rbp)
leaq -0x330(%rbp), %rdi
callq 0xd6d0
leaq -0x318(%rbp), %rdi
callq 0xd880
movl -0x2fc(%rbp), %eax
movl %eax, -0x3a4(%rbp)
testl %eax, %eax
je 0xc29d
jmp 0xc28d
movl -0x3a4(%rbp), %eax
subl $0x3, %eax
je 0xc2b3
jmp 0xc3f3
jmp 0xbdd7
leaq -0x318(%rbp), %rdi
callq 0xd880
jmp 0xc419
movl $0x0, -0x44(%rbp)
movq -0x20(%rbp), %rdi
leaq -0x44(%rbp), %rsi
callq 0x88c0
movq %rax, -0x3b0(%rbp)
jmp 0xc2d0
movq -0x3b0(%rbp), %rax
movq %rax, -0x338(%rbp)
movq -0x338(%rbp), %rsi
leaq -0x2e0(%rbp), %rdi
callq 0xaf40
movl %eax, -0x3b4(%rbp)
jmp 0xc2f9
movl -0x3b4(%rbp), %eax
movl %eax, -0x33c(%rbp)
cmpl $0x1, -0x33c(%rbp)
je 0xc382
leaq -0x2b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9e40
jmp 0xc321
movq 0x6c90(%rip), %rdi      # 0x12fb8
leaq 0x2476(%rip), %rsi      # 0xe7a5
callq 0x44a0
movq %rax, -0x3c0(%rbp)
jmp 0xc33d
movq -0x3c0(%rbp), %rdi
movq 0x6c5d(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc352
movq -0x338(%rbp), %rax
movq %rax, -0x3c8(%rbp)
cmpq $0x0, %rax
je 0xc372
movq -0x3c8(%rbp), %rdi
callq 0x46d0
movb $0x0, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
jmp 0xc3f3
movq 0x6c2f(%rip), %rdi      # 0x12fb8
leaq 0x242f(%rip), %rsi      # 0xe7bf
callq 0x44a0
movq %rax, -0x3d0(%rbp)
jmp 0xc39e
movq -0x3d0(%rbp), %rdi
movq 0x6bfc(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0xc3b3
leaq -0x2b0(%rbp), %rdi
xorl %esi, %esi
callq 0x9e40
jmp 0xc3c3
jmp 0xc3c5
movq -0x338(%rbp), %rax
movq %rax, -0x3d8(%rbp)
cmpq $0x0, %rax
je 0xc3e5
movq -0x3d8(%rbp), %rdi
callq 0x46d0
movb $0x1, -0x1(%rbp)
movl $0x1, -0x2fc(%rbp)
leaq -0x2e0(%rbp), %rdi
callq 0xaf90
leaq -0x2b8(%rbp), %rdi
callq 0xa6d0
leaq -0x2b0(%rbp), %rdi
callq 0xc480
jmp 0xc43f
leaq -0x2e0(%rbp), %rdi
callq 0xaf90
leaq -0x2b8(%rbp), %rdi
callq 0xa6d0
leaq -0x2b0(%rbp), %rdi
callq 0xc480
jmp 0xc44d
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x3e0, %rsp            # imm = 0x3E0
popq %rbp
retq
movq -0x2c0(%rbp), %rdi
callq 0x4900
nopl (%rax)