// File: BelfordZ[P]SimpleFileServer/Server.cpp
// Function: Server::begin_server()
void Server::begin_server()
{
   while (true)
   {

      //
      // Accept on our dispatch ports so that Clients can connect to the Server
      //
      
      if (!server->accept(*dispatchIn))
      {
	 std::cout << "ERROR:Server.cpp:begin_server(): "
		   << "dispatchIn->accept() returned false;"
		   << std::endl;
      }
      
      std::cout << "Receiving frame from Client..." << std::endl;
      if(dispatchIn->recv(currFrame) == -1)
      {
	 std::cout << "Failed:Server.cpp:begin_server(): "
		   << "dispatchIn.recv returned -1"
		   << std::endl;
	 exit(-1);
      }

      //
      // Process the Client response, once we get one. Put it into a Frame.
      //

      std::cout << "Creating a frame from Client response..." << std::endl;
      Frame *dispatchFrame = new Frame(currFrame);
      switch (dispatchFrame->get_frame_type())
      {
	 output_done();
	 case CLIENT_HELLO:
	 {
	    listenParams = new initData;
	    // Delegate an available transfer port to a Client once we have connected
	    pthread_mutex_lock(&mutexLock);
	    int clientPort = portQ.front();
	    portQ.pop();
	    pthread_t *tmp = new pthread_t;
	    threads.push(tmp);
	    pthread_mutex_unlock(&mutexLock);

	    std::string clientPid = dispatchFrame->get_procId();

	    // We need to do this to remove the spaces at the end of the filename...
	    std::string fName = dispatchFrame->get_data();
	    fName = fName.substr(0, fName.find(" "));
    
	    listenParams->filename = fName;
	    listenParams->port = clientPort;

	    // Formulate a SERVER_HELLO message with the port number that we delegated
	    // and send it to the client so they can connect.
	    delete dispatchFrame;
	    dispatchFrame = new Frame(SERVER_HELLO,
				      to_string<int>(clientPort),
				      clientPid);
	    client->accept(*dispatchOut);
	    dispatchOut->send(dispatchFrame->get_frame_as_string());
 
	    // Create the thread AFTER we have sent SERVER_HELLO. If we create it before,
	    // bad things happen... The Client will wait for us to receive the message. (2 seconds)
	    pthread_create(tmp, NULL, process_request, (void*)listenParams);
	    break;	
	 }	       
	 default:
	 {
	    std::cout << "Failed: Server.cpp::dispatchIn.recv returned -1"
		      << std::endl;
	    exit(-1);
	 }
      }
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
movq 0x18(%rax), %rdi
movq (%rax), %rsi
callq 0x9d80
testb $0x1, %al
jne 0x41f2
movq 0xbe10(%rip), %rdi      # 0xffd8
leaq 0x6ebb(%rip), %rsi      # 0xb08a
callq 0x32c0
movq %rax, %rdi
leaq 0x6ece(%rip), %rsi      # 0xb0ac
callq 0x32c0
movq %rax, %rdi
movq 0xbdd3(%rip), %rsi      # 0xffc0
callq 0x3310
movq 0xbddf(%rip), %rdi      # 0xffd8
leaq 0x6ed1(%rip), %rsi      # 0xb0d1
callq 0x32c0
movq %rax, %rdi
movq 0xbdb1(%rip), %rsi      # 0xffc0
callq 0x3310
movq -0xe0(%rbp), %rsi
movq (%rsi), %rdi
addq $0x20, %rsi
callq 0x9e50
cmpl $-0x1, %eax
jne 0x4267
movq 0xbda5(%rip), %rdi      # 0xffd8
leaq 0x6eb6(%rip), %rsi      # 0xb0f0
callq 0x32c0
movq %rax, %rdi
leaq 0x6f07(%rip), %rsi      # 0xb150
callq 0x32c0
movq %rax, %rdi
movq 0xbd68(%rip), %rsi      # 0xffc0
callq 0x3310
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3390
movq 0xbd6a(%rip), %rdi      # 0xffd8
leaq 0x6e9e(%rip), %rsi      # 0xb113
callq 0x32c0
movq %rax, %rdi
movq 0xbd3c(%rip), %rsi      # 0xffc0
callq 0x3310
movl $0x48, %edi
callq 0x32d0
movq -0xe0(%rbp), %rsi
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
addq $0x20, %rsi
callq 0x80a0
jmp 0x42b2
movq -0xe8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5080
testl %eax, %eax
je 0x42f1
jmp 0x45dd
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x48, %esi
callq 0x32e0
jmp 0x460e
movl $0x28, %edi
callq 0x32d0
movq %rax, %rdi
movq %rdi, -0x100(%rbp)
callq 0x50a0
movq -0x100(%rbp), %rax
movq %rax, 0xc028(%rip)      # 0x10340
leaq 0xbff9(%rip), %rdi      # 0x10318
movq %rdi, -0xf0(%rbp)
callq 0x3420
leaq 0xc016(%rip), %rdi      # 0x10348
movq %rdi, -0xf8(%rbp)
callq 0x50c0
movq -0xf8(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x20(%rbp)
callq 0x50e0
movl $0x8, %edi
callq 0x32d0
movq %rax, -0x28(%rbp)
leaq 0xc034(%rip), %rdi      # 0x10398
leaq -0x28(%rbp), %rsi
callq 0x5100
movq -0xf0(%rbp), %rdi
callq 0x3230
movq -0x10(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x5130
movq -0x10(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x5160
jmp 0x4395
leaq 0x6d0e(%rip), %rsi      # 0xb0aa
xorl %eax, %eax
movl %eax, %edx
movq %rdx, -0x108(%rbp)
leaq -0x68(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0x3520
movq -0x110(%rbp), %rsi
movq -0x108(%rbp), %rdx
movq %rax, %rcx
leaq -0x88(%rbp), %rdi
callq 0x3300
jmp 0x43d6
leaq -0x68(%rbp), %rdi
movq %rdi, -0x118(%rbp)
leaq -0x88(%rbp), %rsi
movq %rsi, -0x120(%rbp)
callq 0x33a0
movq -0x120(%rbp), %rdi
callq 0x3548
movq -0x118(%rbp), %rsi
movq 0xbf32(%rip), %rdi      # 0x10340
callq 0x3040
jmp 0x4415
movl -0x20(%rbp), %ecx
movq 0xbf21(%rip), %rax      # 0x10340
movl %ecx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x128(%rbp)
cmpq $0x0, %rax
je 0x4450
movq -0x128(%rbp), %rdi
callq 0x5190
movq -0x128(%rbp), %rdi
movl $0x48, %esi
callq 0x32e0
movl $0x48, %edi
callq 0x32d0
movq %rax, -0x130(%rbp)
jmp 0x4463
movb $0x1, -0xb1(%rbp)
movl $0x1, -0x8c(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x51c0
jmp 0x4486
movq -0x130(%rbp), %rdi
leaq -0x8c(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
leaq -0x48(%rbp), %rcx
callq 0x7f30
jmp 0x44a6
movq -0x130(%rbp), %rax
movb $0x0, -0xb1(%rbp)
movq %rax, -0x10(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x3548
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdi
callq 0x9d80
jmp 0x44da
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x10(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0x8360
jmp 0x44fe
movq -0x138(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x9de0
jmp 0x4513
leaq -0xd8(%rbp), %rdi
callq 0x3548
movq -0x28(%rbp), %rdi
movq 0xbe16(%rip), %rcx      # 0x10340
xorl %eax, %eax
movl %eax, %esi
leaq 0xeb(%rip), %rdx        # 0x4620
callq 0x34e0
leaq -0x68(%rbp), %rdi
callq 0x3548
leaq -0x48(%rbp), %rdi
callq 0x3548
jmp 0x4609
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x45d2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x45c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x4593
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x3548
testb $0x1, -0xb1(%rbp)
jne 0x459e
jmp 0x45af
movq -0x130(%rbp), %rdi
movl $0x48, %esi
callq 0x32e0
jmp 0x45c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x3548
leaq -0x68(%rbp), %rdi
callq 0x3548
leaq -0x48(%rbp), %rdi
callq 0x3548
jmp 0x460e
movq 0xb9f4(%rip), %rdi      # 0xffd8
leaq 0x6b51(%rip), %rsi      # 0xb13c
callq 0x32c0
movq %rax, %rdi
movq 0xb9c6(%rip), %rsi      # 0xffc0
callq 0x3310
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3390
jmp 0x41aa
movq -0x18(%rbp), %rdi
callq 0x3490
nopw (%rax,%rax)