// File: /workspace/github_cpp_makefile_star2_O2/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, %rbx
movq %rdx, %r14
movq %rsi, %r15
movl $0x2, 0x1c(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%rsp)
andq $0x0, 0x40(%rsp)
pushq $0x2
popq %rdi
pushq $0x1
popq %rsi
xorl %edx, %edx
callq 0x3060
testl %eax, %eax
js 0x3b5d
movl %eax, %ebp
leaq 0x7907(%rip), %rsi      # 0xb2b8
pushq $0x10
popq %rdx
movl %eax, %edi
callq 0x3210
testl %eax, %eax
js 0x3b66
leaq 0x1c(%rsp), %rsi
pushq $0x4
popq %rdx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x3160
pushq $0x20
popq %rdx
movl %ebp, %edi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x3160
leaq 0x6(%rsp), %rsi
pushq $0x2
popq %rdx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x30d0
cmpw $0x0, 0x6(%rsp)
je 0x3b24
leaq 0x10(%rsp), %rsi
pushq $0x4
popq %rdx
xorl %r15d, %r15d
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x30d0
movl 0x10(%rsp), %eax
movl %eax, (%rbx)
movl %eax, %r12d
shrl $0xa, %r12d
andl $0x3ff, %eax            # imm = 0x3FF
cmpl $0x1, %eax
sbbl $-0x1, %r12d
leaq 0x28(%rsp), %rbx
cmpl %r15d, %r12d
je 0x3a51
movl %r15d, 0x28(%rsp)
movb $0x0, 0x2c(%rsp)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x5016
incl %r15d
jmp 0x3a32
xorl %ebx, %ebx
leaq 0x20(%rsp), %r15
movl %ebp, 0xc(%rsp)
movzwl 0x6(%rsp), %eax
cmpl %eax, %ebx
jae 0x3b19
movl %ebp, %edi
leaq 0x18(%rsp), %rsi
pushq $0x4
popq %rdx
xorl %ecx, %ecx
callq 0x30d0
movl %ebp, %edi
leaq 0x8(%rsp), %rsi
pushq $0x2
popq %rdx
xorl %ecx, %ecx
callq 0x30d0
movl %ebp, %edi
leaq 0xa(%rsp), %rsi
pushq $0x2
popq %rdx
xorl %ecx, %ecx
callq 0x30d0
xorl %r13d, %r13d
movzwl 0xa(%rsp), %eax
cmpl %eax, %r13d
jae 0x3b12
movl %ebp, %edi
leaq 0x14(%rsp), %rsi
pushq $0x4
popq %rdx
xorl %ecx, %ecx
callq 0x30d0
movq %rbx, %rbp
pushq $0x8
popq %rbx
xorl %r12d, %r12d
movq (%r14), %rdi
movq 0x8(%r14), %rax
subq %rdi, %rax
sarq $0x5, %rax
cmpq %r12, %rax
jbe 0x3b06
movl -0x8(%rdi,%rbx), %eax
cmpl 0x14(%rsp), %eax
jne 0x3afd
movl 0x18(%rsp), %eax
movl %eax, 0x20(%rsp)
movzwl 0x8(%rsp), %eax
movw %ax, 0x24(%rsp)
addq %rbx, %rdi
movq %r15, %rsi
callq 0x5042
incq %r12
addq $0x20, %rbx
jmp 0x3ac3
incl %r13d
movq %rbp, %rbx
movl 0xc(%rsp), %ebp
jmp 0x3a9f
incl %ebx
jmp 0x3a5c
xorl %ebx, %ebx
movl %ebp, %edi
callq 0x34c0
jmp 0x3b42
movq 0x74a5(%rip), %rdi      # 0xafd0
leaq 0x3545(%rip), %rsi      # 0x7077
callq 0x32a0
movq %rax, %rdi
callq 0x3150
pushq $-0x1
popq %rbx
leaq 0x30(%rsp), %rdi
callq 0x5460
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x34b7(%rip), %rdi      # 0x701b
jmp 0x3b6d
leaq 0x34c6(%rip), %rdi      # 0x7033
callq 0x3220
xorl %edi, %edi
callq 0x3300
jmp 0x3b83
jmp 0x3b83
jmp 0x3b83
jmp 0x3b83
jmp 0x3b83
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x5460
movq %rbx, %rdi
callq 0x3440