// File: bchu7796[P]p2p-file-sharing/peers.cpp
// Function: client::execute()
int client::execute(void){
    client myclient;
    int process_fd;
    int server_fd;
    struct sockaddr_in client_address, peer_address;
    /* initialize random seed: */
    srand (time(NULL));

    //initialize server
    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = PF_INET; 
    server_address.sin_addr.s_addr = inet_addr(SERVER_IP); 
    server_address.sin_port = htons(SERVER_PORT); 

    //create thread for user interface
    std::thread user_thread(&client::user_interface, myclient);
    user_thread.detach();

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

    //initailize address structure
    bzero(&peer_address, sizeof(peer_address));
    peer_address.sin_family = PF_INET; 
    peer_address.sin_addr.s_addr = INADDR_ANY; 
    peer_address.sin_port = htons(PORT); 

    //bind socket
    if(bind(server_fd, (struct sockaddr*) &peer_address, sizeof(peer_address)) < 0){
        perror("Failed to bind"); 
        exit(0);
    }

    //listen socket
    if(listen(server_fd, 5) < 0){
        perror("Failed to listen"); 
        exit(0);
    }


    while(1){
        int client_address_length = sizeof(client_address);
        if((process_fd = accept(server_fd,(struct sockaddr*) &client_address, (socklen_t *) &client_address_length)) < 0){
            perror("Failed to accept"); 
            exit(0);
        }
        else{
            std::string file_name;
            int chunk_index;
            uint32_t request_type;
            recv(process_fd, &file_name, sizeof(file_name), 0);
            recv(process_fd, &chunk_index, sizeof(chunk_index), 0);
            std::cout<<"upload file:" << file_name <<"," <<chunk_index<<std::endl;
            //use multi-thread to handle requests
            std::thread tid(&client::handle_request, myclient, process_fd, file_name, chunk_index);
            tid.detach();
        }
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x32b0
movl %eax, %edi
callq 0x32c0
xorps %xmm0, %xmm0
movups %xmm0, 0xe6f7(%rip)     # 0x142e0
movw $0x2, 0xe6ee(%rip)      # 0x142e0
leaq 0x74f3(%rip), %rdi      # 0xd0ec
callq 0x32f0
movl %eax, 0xe6e0(%rip)      # 0x142e4
movl $0x1f90, %edi           # imm = 0x1F90
callq 0x3050
movw %ax, 0xe6cd(%rip)       # 0x142e2
leaq -0x25c(%rip), %rax      # 0x59c0
movq %rax, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
leaq -0x50(%rbp), %rsi
leaq -0x9(%rbp), %rdx
callq 0x6a30
movq -0xa8(%rbp), %rdi
callq 0x3490
jmp 0x5c4e
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x3080
movl %eax, -0x14(%rbp)
cmpl $0x0, %eax
jge 0x5c8d
leaq 0x73ad(%rip), %rdi      # 0xd01b
callq 0x3250
jmp 0x5c75
xorl %edi, %edi
callq 0x3340
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5ead
leaq -0x34(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x31a0
movw $0x2, -0x34(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x1f92, %edi           # imm = 0x1F92
callq 0x3050
movw %ax, -0x32(%rbp)
movl -0x14(%rbp), %edi
leaq -0x34(%rbp), %rsi
movl $0x10, %edx
callq 0x3060
cmpl $0x0, %eax
jge 0x5ce3
leaq 0x7421(%rip), %rdi      # 0xd0f6
callq 0x3250
jmp 0x5cdc
xorl %edi, %edi
callq 0x3340
movl -0x14(%rbp), %edi
movl $0x5, %esi
callq 0x3320
cmpl $0x0, %eax
jge 0x5d0a
leaq 0x7409(%rip), %rdi      # 0xd105
callq 0x3250
jmp 0x5d03
xorl %edi, %edi
callq 0x3340
jmp 0x5d0c
jmp 0x5d0e
movl $0x10, -0x60(%rbp)
movl -0x14(%rbp), %edi
leaq -0x24(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x30e0
movl %eax, -0xac(%rbp)
jmp 0x5d2d
movl -0xac(%rbp), %eax
movl %eax, -0x10(%rbp)
cmpl $0x0, %eax
jge 0x5d50
leaq 0x73d4(%rip), %rdi      # 0xd116
callq 0x3250
jmp 0x5d49
xorl %edi, %edi
callq 0x3340
leaq -0x80(%rbp), %rdi
movq %rdi, -0xb8(%rbp)
callq 0x33c0
movq -0xb8(%rbp), %rsi
movl -0x10(%rbp), %edi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x5d78
movl -0x10(%rbp), %edi
leaq -0x84(%rbp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x30f0
jmp 0x5d90
movq 0xe239(%rip), %rdi      # 0x13fd0
leaq 0x7389(%rip), %rsi      # 0xd127
callq 0x32d0
movq %rax, -0xc0(%rbp)
jmp 0x5dac
movq -0xc0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3280
movq %rax, -0xc8(%rbp)
jmp 0x5dc5
movq -0xc8(%rbp), %rdi
leaq 0x7361(%rip), %rsi      # 0xd134
callq 0x32d0
movq %rax, -0xd0(%rbp)
jmp 0x5de1
movq -0xd0(%rbp), %rdi
movl -0x84(%rbp), %esi
callq 0x3480
movq %rax, -0xd8(%rbp)
jmp 0x5dfc
movq -0xd8(%rbp), %rdi
movq 0xe1ae(%rip), %rsi      # 0x13fb8
callq 0x3310
jmp 0x5e11
leaq -0x358(%rip), %rax      # 0x5ac0
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
leaq -0x9(%rbp), %rdx
leaq -0x10(%rbp), %rcx
leaq -0x80(%rbp), %r8
leaq -0x84(%rbp), %r9
callq 0x6af0
jmp 0x5e52
leaq -0x90(%rbp), %rdi
callq 0x3490
jmp 0x5e60
leaq -0x90(%rbp), %rdi
callq 0x6790
leaq -0x80(%rbp), %rdi
callq 0x31d0
jmp 0x5ea8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5e9d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x6790
leaq -0x80(%rbp), %rdi
callq 0x31d0
jmp 0x5ead
jmp 0x5d0c
leaq -0x40(%rbp), %rdi
callq 0x6790
movq -0x58(%rbp), %rdi
callq 0x34a0
nop