// File: 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
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rsi, -0xa8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0x2, -0x30(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5f70
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x3080
movl %eax, -0x2c(%rbp)
cmpl $0x0, %eax
jge 0x3c35
leaq 0x940e(%rip), %rdi      # 0xd01b
callq 0x3250
jmp 0x3c14
xorl %edi, %edi
callq 0x3340
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x60b0
jmp 0x3ef4
movl -0x2c(%rbp), %edi
leaq 0x106a1(%rip), %rsi     # 0x142e0
movl $0x10, %edx
callq 0x3240
movl %eax, -0xac(%rbp)
jmp 0x3c51
movl -0xac(%rbp), %eax
cmpl $0x0, %eax
jge 0x3c71
leaq 0x93d0(%rip), %rdi      # 0xd033
callq 0x3250
jmp 0x3c6a
xorl %edi, %edi
callq 0x3340
movl -0x2c(%rbp), %edi
leaq -0x30(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x3180
jmp 0x3c86
movq -0xa8(%rbp), %rsi
movl -0x2c(%rbp), %edi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x3180
jmp 0x3c9e
movl -0x2c(%rbp), %edi
leaq -0x32(%rbp), %rsi
movl $0x2, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3cb3
movzwl -0x32(%rbp), %eax
cmpl $0x0, %eax
jne 0x3d00
movq 0x1030d(%rip), %rdi     # 0x13fd0
leaq 0x93ad(%rip), %rsi      # 0xd077
callq 0x32d0
movq %rax, -0xb8(%rbp)
jmp 0x3cd8
movq -0xb8(%rbp), %rdi
movq 0x102d2(%rip), %rsi     # 0x13fb8
callq 0x3310
jmp 0x3ced
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x80(%rbp)
jmp 0x3edf
movl -0x2c(%rbp), %edi
leaq -0x48(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3d15
movq -0xa0(%rbp), %rdi
movl -0x48(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movl -0x48(%rbp), %esi
callq 0x36e0
movl %eax, -0x84(%rbp)
movl $0x0, -0x88(%rbp)
movl -0x88(%rbp), %eax
cmpl -0x84(%rbp), %eax
jge 0x3d7a
movl -0x88(%rbp), %eax
movl %eax, -0x68(%rbp)
movb $0x0, -0x64(%rbp)
movq -0x20(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x5f90
jmp 0x3d67
jmp 0x3d69
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x3d3d
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movzwl -0x32(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3ec7
movl -0x2c(%rbp), %edi
leaq -0x38(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3dab
movl -0x2c(%rbp), %edi
leaq -0x3a(%rbp), %rsi
movl $0x2, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3dc0
movl -0x38(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x2c(%rbp), %edi
leaq -0x34(%rbp), %rsi
movl $0x2, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3ddb
movl $0x0, -0x90(%rbp)
movl -0x90(%rbp), %eax
movzwl -0x34(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3eb1
movl -0x2c(%rbp), %edi
leaq -0x44(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x3e0c
movl $0x0, -0x94(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6000
movq %rax, %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
jae 0x3e9b
movq -0x20(%rbp), %rdi
movslq -0x94(%rbp), %rsi
callq 0x6020
movl (%rax), %eax
cmpl -0x44(%rbp), %eax
jne 0x3e85
movl -0x38(%rbp), %eax
movl %eax, -0x70(%rbp)
movw -0x3a(%rbp), %ax
movw %ax, -0x6c(%rbp)
movq -0x20(%rbp), %rdi
movslq -0x94(%rbp), %rsi
callq 0x6020
movq %rax, %rdi
addq $0x8, %rdi
leaq -0x70(%rbp), %rsi
callq 0x6040
jmp 0x3e83
jmp 0x3e85
jmp 0x3e87
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x3e16
jmp 0x3e9d
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x90(%rbp)
jmp 0x3de5
jmp 0x3eb3
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x3d84
movl -0x2c(%rbp), %edi
callq 0x3510
jmp 0x3ed1
movl $0x0, -0x4(%rbp)
movl $0x1, -0x80(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x60b0
movl -0x4(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x34a0
nopl (%rax)