// File: prakhar2808[P]DBEngine/serverCode/server.cc
// Function: main
int main(int argc, char** argv) {

  int server_socket, client_socket, addr_size;
  SA_IN server_addr, client_addr;

  for(int i = 0; i < THREAD_POOL_SIZE; i++) {
    pthread_create(&thread_pool[i], NULL, thread_function, NULL);
  }

  check((server_socket = socket(AF_INET, SOCK_STREAM, 0)), 
        "Failed to create socket");
  
  // Initializing address struct
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = INADDR_ANY;
  server_addr.sin_port = htons(SERVERPORT);

  check(bind(server_socket, (SA*)&server_addr, sizeof(server_addr)),
        "Bind failed!");
  check(listen(server_socket, SERVER_BACKLOG),
        "Listen failed!");

  // Create database object reference
  dbObjectRef = new database();

  while(true) {

    printf("Waiting for connections...\n");
    addr_size = sizeof(SA_IN);

    check(client_socket = 
        accept(server_socket, (SA*)&client_addr, (socklen_t*)&addr_size),
        "accept failed");
    printf("Connected!\n");
    
    // Put the connection somewhere so that an available thread can find it.
    int* pclient = (int*)malloc(sizeof(int));
    *pclient = client_socket;
    pthread_mutex_lock(&mutex);
    conn_queue.push(pclient);
    // Signal that a job has arrived in the queue.
    pthread_cond_signal(&condition_var);
    pthread_mutex_unlock(&mutex);
  }
  delete dbObjectRef;
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x40(%rbp)
cmpl $0xa, -0x40(%rbp)
jge 0x3db63
movslq -0x40(%rbp), %rax
leaq 0x21e32(%rip), %rdi     # 0x5f970
shlq $0x3, %rax
addq %rax, %rdi
xorl %eax, %eax
movl %eax, %ecx
leaq 0x170(%rip), %rdx       # 0x3dcc0
movq %rcx, %rsi
callq 0x6910
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x3db2d
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x6110
movl %eax, %edi
movl %edi, -0x14(%rbp)
leaq 0x3a95(%rip), %rsi      # 0x41615
callq 0x3dd50
movw $0x2, -0x2c(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x3039, %edi           # imm = 0x3039
callq 0x60a0
movw %ax, -0x2a(%rbp)
movl -0x14(%rbp), %edi
leaq -0x2c(%rbp), %rsi
movl $0x10, %edx
callq 0x60c0
movl %eax, %edi
leaq 0x3a73(%rip), %rsi      # 0x4162d
callq 0x3dd50
movl -0x14(%rbp), %edi
movl $0x64, %esi
callq 0x65b0
movl %eax, %edi
leaq 0x3a65(%rip), %rsi      # 0x4163a
callq 0x3dd50
movl $0x10, %edi
callq 0x64f0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x60(%rbp)
callq 0x92c0
jmp 0x3dbf5
movq -0x60(%rbp), %rax
movq %rax, 0x21e68(%rip)     # 0x5fa68
leaq 0x3a42(%rip), %rdi      # 0x41649
movb $0x0, %al
callq 0x6080
movl $0x10, -0x1c(%rbp)
movl -0x14(%rbp), %edi
leaq -0x3c(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x6180
movl %eax, %edi
movl %edi, -0x18(%rbp)
leaq 0x3a34(%rip), %rsi      # 0x41665
callq 0x3dd50
leaq 0x3a36(%rip), %rdi      # 0x41673
movb $0x0, %al
callq 0x6080
movl $0x4, %edi
callq 0x66b0
movq %rax, -0x58(%rbp)
movl -0x18(%rbp), %ecx
movq -0x58(%rbp), %rax
movl %ecx, (%rax)
leaq 0x21dae(%rip), %rdi     # 0x5fa10
callq 0x6750
leaq 0x21d52(%rip), %rdi     # 0x5f9c0
leaq -0x58(%rbp), %rsi
callq 0x3e5e0
leaq 0x21dba(%rip), %rdi     # 0x5fa38
callq 0x6040
leaq 0x21d86(%rip), %rdi     # 0x5fa10
callq 0x63f0
jmp 0x3dc00
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x10, %esi
callq 0x6500
movq -0x48(%rbp), %rdi
callq 0x68c0
nopw (%rax,%rax)