// File: /workspace/github_cpp_makefile_star2_O2/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 0x31e3
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)
pushq $0x2
popq %rdi
movl %edi, %esi
xorl %edx, %edx
callq 0x2070
cmpl $-0x1, %eax
jne 0x3232
leaq 0x10d4(%rip), %rdi      # 0x42b0
callq 0x2170
jmp 0x322a
movq 0x2dde(%rip), %r14      # 0x5fc8
leaq 0x1083(%rip), %rsi      # 0x4274
movq %r14, %rdi
callq 0x21b0
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x21b0
leaq 0x106f(%rip), %rsi      # 0x427a
movq %rax, %rdi
callq 0x21b0
leaq 0x1062(%rip), %rsi      # 0x427c
movq %r14, %rdi
callq 0x21b0
movq %rax, %rdi
callq 0x20f0
pushq $0x1
popq %rdi
callq 0x2200
movl %eax, %ebx
pushq $0x3
popq %rsi
movl %eax, %edi
xorl %eax, %eax
callq 0x2120
orl $0x800, %eax            # imm = 0x800
pushq $0x4
popq %rsi
movl %ebx, %edi
movl %eax, %edx
xorl %eax, %eax
callq 0x2120
leaq -0x30(%rbp), %rsi
andq $0x0, 0x8(%rsi)
movq $0x42270002, (%rsi)     # imm = 0x42270002
pushq $0x10
popq %rdx
movl %ebx, %edi
callq 0x2060
cmpl $-0x1, %eax
jne 0x3297
movq 0x2d57(%rip), %rax      # 0x5fd0
movq (%rax), %rcx
leaq 0x104d(%rip), %rdi      # 0x42d0
pushq $0x1e
popq %rsi
pushq $0x1
popq %rdx
callq 0x22a0
movl %ebx, %edi
callq 0x22b0
jmp 0x322a
leaq 0x1051(%rip), %rdi      # 0x42ef
movl $0x2742, %esi           # imm = 0x2742
xorl %eax, %eax
callq 0x2040
leaq -0x20(%rbp), %rsi
movl %ebx, %edi
callq 0x2510
movl %ebx, %edi
callq 0x22b0
xorl %edi, %edi
callq 0x2200
nop