// File: /workspace/github_cpp_makefile_star2_O3/bchu7796[P]p2p-file-sharing/peers.cpp
// Function: client::location_request(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::vector<chunk, std::allocator<chunk>>&, int&)
int client::location_request(std::string file_name, std::vector<chunk>& chunks, int & file_size){
    /*
    send:
        request type
        file name
    receive:
        number_of_location
        file_length
        a list of ip_address
        a list of port
        a list of number_of_chunks
        a list of chunk index for every ip_address

    */
    int peer_fd;
    const uint32_t request_type = 2;
    uint16_t number_of_location;
    uint16_t number_of_chunk;
    uint32_t ip_address;
    uint16_t port;
    struct in_addr temp_address;
    uint32_t chunk_index;
    uint32_t file_length;
    //std::vector<chunk> chunks;
    struct chunk temp_chunk;
    struct peer temp_peer;

    //create socket
    if((peer_fd = socket(AF_INET, SOCK_STREAM , 0)) < 0){
        perror("Failed to create socket"); 
        exit(0);
    }

    //connect to server
    if(connect(peer_fd,(struct sockaddr*) &server_address, sizeof(server_address)) < 0){
        perror("Failed to connect"); 
        exit(0);
    }

    //ask for list of addresses having the file
    send(peer_fd, &request_type, sizeof(request_type), 0);
    send(peer_fd, &file_name, sizeof(file_name), 0);
    recv(peer_fd, &number_of_location, sizeof(number_of_location), 0);
    
    //file is not found
    if(number_of_location == 0){
        std::cout<<"file not found"<<std::endl;
        return -1;
    }
    //create data structure to store file location info
    recv(peer_fd, &file_length, sizeof(file_length), 0);
    file_size = file_length;
    int chunk_number = calculate_chunk_number(file_length);
    for(int i = 0; i<chunk_number; i++){
        temp_chunk.index = i;
        temp_chunk.is_possessed = false;
        chunks.push_back(temp_chunk);
    }

   //store the routing information into client's data structure.
    for(int i=0; i<number_of_location; i++){
        recv(peer_fd, &ip_address, sizeof(ip_address), 0);
        recv(peer_fd, &port, sizeof(port), 0);
        temp_address.s_addr = ip_address;

        recv(peer_fd, &number_of_chunk, sizeof(number_of_chunk), 0);
        for(int j=0; j<number_of_chunk; j++){
            recv(peer_fd, &chunk_index, sizeof(chunk_index), 0);
            for(int k = 0; k<chunks.size(); k++){
                if(chunks[k].index == chunk_index){
                    temp_peer.address.s_addr = ip_address;
                    temp_peer.port = port;
                    chunks[k].peers.push_back(temp_peer);
                }
            }
        }
    }
    close(peer_fd);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %r14
movq %rdx, %rbx
movq %rsi, %r15
movl $0x2, 0x1c(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x3070
testl %eax, %eax
js 0x3e2f
movl %eax, %ebp
leaq 0x76e6(%rip), %rsi      # 0xb2d8
movl %eax, %edi
movl $0x10, %edx
callq 0x3240
testl %eax, %eax
js 0x3e34
leaq 0x1c(%rsp), %rsi
movl $0x4, %edx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x3160
movl $0x20, %edx
movl %ebp, %edi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x3160
leaq 0x2(%rsp), %rsi
movl $0x2, %edx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x30e0
cmpw $0x0, 0x2(%rsp)
je 0x3dbc
leaq 0x10(%rsp), %rsi
movl $0x4, %edx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x30e0
movl 0x10(%rsp), %eax
movl %eax, (%r14)
movl %eax, %ecx
shrl $0xa, %ecx
xorl %r15d, %r15d
testl $0x3ff, %eax            # imm = 0x3FF
setne %r15b
addl %ecx, %r15d
je 0x3c9e
xorl %r12d, %r12d
leaq 0x28(%rsp), %r14
movl %r12d, 0x28(%rsp)
movb $0x0, 0x2c(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5ca2
incl %r12d
cmpl %r12d, %r15d
jne 0x3c81
cmpw $0x0, 0x2(%rsp)
je 0x3db1
movq $0x0, 0x20(%rsp)
leaq 0x8(%rsp), %r14
movl $0x4, %edx
movl %ebp, %edi
leaq 0x18(%rsp), %rsi
xorl %ecx, %ecx
callq 0x30e0
movl $0x2, %edx
movl %ebp, %edi
leaq 0x6(%rsp), %rsi
xorl %ecx, %ecx
callq 0x30e0
movl $0x2, %edx
movl %ebp, %edi
leaq 0x4(%rsp), %rsi
xorl %ecx, %ecx
callq 0x30e0
cmpw $0x0, 0x4(%rsp)
je 0x3d98
xorl %r12d, %r12d
movl $0x4, %edx
movl %ebp, %edi
leaq 0x14(%rsp), %rsi
xorl %ecx, %ecx
callq 0x30e0
movq (%rbx), %rax
cmpq %rax, 0x8(%rbx)
je 0x3d87
movl $0x18, %r15d
xorl %r13d, %r13d
movl -0x18(%rax,%r15), %ecx
cmpl 0x14(%rsp), %ecx
jne 0x3d6d
movl 0x18(%rsp), %ecx
movl %ecx, 0x8(%rsp)
movzwl 0x6(%rsp), %ecx
movw %cx, 0xc(%rsp)
movq -0x8(%rax,%r15), %rsi
cmpq (%rax,%r15), %rsi
je 0x3d5d
movq 0x8(%rsp), %rcx
movq %rcx, (%rsi)
addq $0x8, -0x8(%rax,%r15)
jmp 0x3d6d
leaq (%rax,%r15), %rdi
addq $-0x10, %rdi
movq %r14, %rdx
callq 0x6538
incq %r13
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
addq $0x20, %r15
cmpq %r13, %rcx
ja 0x3d25
incl %r12d
movzwl 0x4(%rsp), %eax
cmpl %eax, %r12d
jb 0x3d00
movq 0x20(%rsp), %rcx
incl %ecx
movzwl 0x2(%rsp), %eax
movq %rcx, 0x20(%rsp)
cmpl %eax, %ecx
jb 0x3cb8
xorl %ebx, %ebx
movl %ebp, %edi
callq 0x3500
jmp 0x3e07
movq 0x720d(%rip), %rbx      # 0xafd0
leaq 0x42c2(%rip), %rsi      # 0x808c
movl $0xe, %edx
movq %rbx, %rdi
callq 0x3330
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x32d0
movsbl %al, %esi
movq 0x71db(%rip), %rdi      # 0xafd0
callq 0x3030
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x31d0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3e1e
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x3300
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x3584
callq 0x3570
jmp 0x3e43
jmp 0x3e43
jmp 0x3e43
jmp 0x3e43
jmp 0x3e43
movq %rax, %rbx
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3e5d
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x3300
movq %rbx, %rdi
callq 0x3480
nop