// File: luisremis[P]SDFS/FileSystem.cpp
// Function: FileSystem::getFromAddress(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
bool FileSystem::getFromAddress(std::string address, std::string localFile, std::string remoteFile)
{
    int connectionToServer; //TCP connect to introducer/other nodes

    logFile << "getFromAddress: Connecting to "<< address << "..." << std::endl;

    int ret = connect_to_server(address.c_str(), port, &connectionToServer);
    if(ret!=0)
    {
        logFile <<"ERROR getFromAddress: Cannot connect to "<<address<< std::endl;
        std::cout <<"ERROR getFromAddress: Cannot connect to "<<address<< std::endl;
        return false;
    }
    else{
        
        Message_fs msg;
        msg.type = MSG_GET;
        memset(msg.filename, '\0', 200);
        remoteFile.copy(msg.filename, remoteFile.length());

        write(connectionToServer, &msg, sizeof(Message_fs)); // Send filename
        read (connectionToServer, &msg, sizeof(Message_fs)); // Receive size

        if (msg.size == 0)
        {
            std::cout << "File does not exist: " << remoteFile << std::endl;
            close(connectionToServer);
            return false;
        }
        else
        {
            char * buffer = new char [msg.size];

            //size_t ret = read(connectionToServer, buffer,  msg.size);
            size_t ret =splitRead( connectionToServer, buffer, msg.size );
            // std::cout << "getFromAddress: Received: " << ret <<" of "<<msg.size << std::endl;

            std::ofstream file(localFile, std::ofstream::binary);

            if (!file.good())
            {
                std::cout << "Could not open file: " << localFile << std::endl;
                logFile << "Could not open file: " << localFile << std::endl;
                return false;
            }

            file.write(buffer, msg.size); 
            file.close();  

            delete buffer;

            close(connectionToServer);
            return true;
        }        
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x390, %rsp            # imm = 0x390
movq %rsi, -0x340(%rbp)
movq %rdx, -0x350(%rbp)
movq %rcx, -0x348(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x338(%rbp)
leaq 0xafd3(%rip), %rsi      # 0x1cc45
callq 0x43f0
movq -0x340(%rbp), %rsi
movq %rax, %rdi
callq 0x4370
movq %rax, %rdi
leaq 0xab28(%rip), %rsi      # 0x1c7b8
callq 0x43f0
movq %rax, %rdi
movq 0x15309(%rip), %rsi     # 0x26fa8
callq 0x4410
movq -0x340(%rbp), %rdi
callq 0x41d0
movq %rax, %rdi
movq -0x338(%rbp), %rax
movl 0x200(%rax), %esi
leaq -0x2c(%rbp), %rdx
callq 0x1aaf0
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x11d3d
movq -0x338(%rbp), %rdi
leaq 0xaf84(%rip), %rsi      # 0x1cc64
callq 0x43f0
movq -0x340(%rbp), %rsi
movq %rax, %rdi
callq 0x4370
movq %rax, %rdi
movq 0x152aa(%rip), %rsi     # 0x26fa8
callq 0x4410
movq 0x152b6(%rip), %rdi     # 0x26fc0
leaq 0xaf53(%rip), %rsi      # 0x1cc64
callq 0x43f0
movq -0x340(%rbp), %rsi
movq %rax, %rdi
callq 0x4370
movq %rax, %rdi
movq 0x15279(%rip), %rsi     # 0x26fa8
callq 0x4410
movb $0x0, -0x1(%rbp)
jmp 0x11fae
movl $0x1, -0x110(%rbp)
leaq -0x110(%rbp), %rdi
addq $0x4, %rdi
xorl %esi, %esi
movl $0xc8, %edx
callq 0x4240
movq -0x348(%rbp), %rdi
leaq -0x110(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x358(%rbp)
callq 0x4590
movq -0x348(%rbp), %rdi
movq -0x358(%rbp), %rsi
movq %rax, %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x40c0
movl -0x2c(%rbp), %edi
leaq -0x110(%rbp), %rsi
movl $0xe0, %edx
callq 0x4190
movl -0x2c(%rbp), %edi
leaq -0x110(%rbp), %rsi
movl $0xe0, %edx
callq 0x4560
cmpq $0x0, -0x40(%rbp)
jne 0x11e07
movq 0x151f4(%rip), %rdi     # 0x26fc0
leaq 0xaeba(%rip), %rsi      # 0x1cc8d
callq 0x43f0
movq -0x348(%rbp), %rsi
movq %rax, %rdi
callq 0x4370
movq %rax, %rdi
movq 0x151b7(%rip), %rsi     # 0x26fa8
callq 0x4410
movl -0x2c(%rbp), %edi
callq 0x4740
movb $0x0, -0x1(%rbp)
jmp 0x11fae
movq -0x40(%rbp), %rdi
callq 0x4030
movq %rax, -0x118(%rbp)
movl -0x2c(%rbp), %edi
movq -0x118(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x1af30
movq -0x350(%rbp), %rsi
movq %rax, -0x120(%rbp)
leaq -0x320(%rbp), %rdi
movl $0x4, %edx
callq 0x4720
movq -0x320(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x320(%rbp,%rax), %rdi
callq 0x4620
movb %al, -0x359(%rbp)
jmp 0x11e69
movb -0x359(%rbp), %al
testb $0x1, %al
jne 0x11f43
jmp 0x11e79
movq 0x15140(%rip), %rdi     # 0x26fc0
leaq 0xad15(%rip), %rsi      # 0x1cb9c
callq 0x43f0
movq %rax, -0x368(%rbp)
jmp 0x11e95
movq -0x350(%rbp), %rsi
movq -0x368(%rbp), %rdi
callq 0x4370
movq %rax, -0x370(%rbp)
jmp 0x11eb1
movq -0x370(%rbp), %rdi
movq 0x150e9(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x11ec6
movq -0x338(%rbp), %rdi
leaq 0xacc8(%rip), %rsi      # 0x1cb9c
callq 0x43f0
movq %rax, -0x378(%rbp)
jmp 0x11ee2
movq -0x350(%rbp), %rsi
movq -0x378(%rbp), %rdi
callq 0x4370
movq %rax, -0x380(%rbp)
jmp 0x11efe
movq -0x380(%rbp), %rdi
movq 0x1509c(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x11f13
movb $0x0, -0x1(%rbp)
movl $0x1, -0x330(%rbp)
jmp 0x11fa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x328(%rbp)
movl %eax, -0x32c(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x4768
jmp 0x11fbc
movq -0x118(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0x320(%rbp), %rdi
callq 0x44d0
jmp 0x11f5c
leaq -0x320(%rbp), %rdi
callq 0x4550
jmp 0x11f6a
movq -0x118(%rbp), %rax
movq %rax, -0x388(%rbp)
cmpq $0x0, %rax
je 0x11f8a
movq -0x388(%rbp), %rdi
callq 0x43c0
movl -0x2c(%rbp), %edi
callq 0x4740
jmp 0x11f94
movb $0x1, -0x1(%rbp)
movl $0x1, -0x330(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x4768
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x390, %rsp            # imm = 0x390
popq %rbp
retq
movq -0x328(%rbp), %rdi
callq 0x46a0
nopl (%rax,%rax)