// File: /workspace/github_cpp_makefile_star2_O3/maclellant[P]ReliableGoBackN/server.cpp
// Function: main
int main(int argc, char** argv)
{
	if (argc != 5)
    {
        std::cout << "Usage: " << argv[0] << " ";
        std::cout << "<corrupt %%> <loss %%> <delay %%> <delay-amount-ms>" << std::endl;
        exit(EXIT_FAILURE);
    }

    GremlinInfo gremlin_info;

    gremlin_info.corrupt_chance = atoi(argv[1]);
    gremlin_info.loss_chance = atoi(argv[2]);
    gremlin_info.delay_chance = atoi(argv[3]);
    gremlin_info.delay_amount_ms = atoi(argv[4]);

	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
    int sockfd = -1; 

    socklen_t slen = sizeof(client_addr);

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
    	perror("Error: Could not create socket\n");
    	exit(EXIT_FAILURE);
    }

    // Set the receiving function to non-blocking
    int flags = fcntl(sockfd, F_GETFL);
    flags |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, flags);

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) == -1)
    {
    	fprintf(stderr, "Error: Could not bind to port\n");
    	close(sockfd);
    	exit(EXIT_FAILURE);
    }

    printf("Successfully bound server to port %d and listening for clients...\n\n", SERVER_PORT);
	
	receive_commands(sockfd, gremlin_info); // include params for gremlin?
 
    close(sockfd);
    exit(EXIT_SUCCESS);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rsi, %rbx
cmpl $0x5, %edi
jne 0x3709
movq 0x8(%rbx), %rdi
callq 0x2250
movl %eax, -0x18(%rbp)
movq 0x10(%rbx), %rdi
callq 0x2250
movl %eax, -0x1c(%rbp)
movq 0x18(%rbx), %rdi
callq 0x2250
movl %eax, -0x20(%rbp)
movq 0x20(%rbx), %rdi
callq 0x2250
movl %eax, -0x14(%rbp)
movl $0x2, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x2080
cmpl $-0x1, %eax
jne 0x375a
leaq 0xbae(%rip), %rdi       # 0x42b0
callq 0x2160
jmp 0x3750
movq 0x28b8(%rip), %r14      # 0x5fc8
leaq 0xb5d(%rip), %rsi       # 0x4274
movq %r14, %rdi
callq 0x21b0
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x21b0
leaq 0xb49(%rip), %rsi       # 0x427a
movq %rax, %rdi
callq 0x21b0
leaq 0xb3c(%rip), %rsi       # 0x427c
movq %r14, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20d0
movl $0x1, %edi
callq 0x2210
movl %eax, %ebx
movl %eax, %edi
movl $0x3, %esi
xorl %eax, %eax
callq 0x2100
orl $0x800, %eax            # imm = 0x800
movl %ebx, %edi
movl $0x4, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x2100
leaq -0x30(%rbp), %rsi
movq $0x0, 0x8(%rsi)
movq $0x42270002, (%rsi)     # imm = 0x42270002
movl %ebx, %edi
movl $0x10, %edx
callq 0x2070
cmpl $-0x1, %eax
jne 0x37cc
movq 0x2826(%rip), %rax      # 0x5fd0
movq (%rax), %rcx
leaq 0xb1c(%rip), %rdi       # 0x42d0
movl $0x1e, %esi
movl $0x1, %edx
callq 0x22a0
movl %ebx, %edi
callq 0x22b0
jmp 0x3750
leaq 0xb1c(%rip), %rdi       # 0x42ef
movl $0x2742, %esi           # imm = 0x2742
xorl %eax, %eax
callq 0x2050
leaq -0x20(%rbp), %rsi
movl %ebx, %edi
callq 0x255d
movl %ebx, %edi
callq 0x22b0
xorl %edi, %edi
callq 0x2210