// File: /workspace/github_cpp_makefile_star2_O2/prakhar2808[P]DBEngine/clientCode/client.cc
// Function: main
int main(int argc, char** argv) {

  struct hostent* host = gethostbyname(serverIp.c_str()); 
  sockaddr_in sendSockAddr;   
  bzero((char*)&sendSockAddr, sizeof(sendSockAddr)); 
  sendSockAddr.sin_family = AF_INET; 
  sendSockAddr.sin_addr.s_addr = 
    inet_addr(inet_ntoa(*(struct in_addr*)*host->h_addr_list));
  sendSockAddr.sin_port = htons(port);
  clientSd = socket(AF_INET, SOCK_STREAM, 0);
    
  int status = connect(clientSd,
                      (sockaddr*) &sendSockAddr, 
                      sizeof(sendSockAddr));
  if(status < 0) {
    std::cout << "Error connecting to socket!" 
              << std::endl; 
    return status;
  }
    
  std::cout << "Connected to the server!" 
            << std::endl;

  // First message
  recv(clientSd, buffer, sizeof(buffer), 0);
  std::cout << buffer << std::endl;
  
  // Check if the client has sent a file name to dump in the db
  if(argc == 2) {
    std::cout << "Please wait! Dumping input file to the database ... "
              << std::endl;
    auto t_start = std::chrono::high_resolution_clock::now();
    std::ifstream fd;
    fd.open(argv[1]);
    fd >> std::noskipws;
    unsigned char len;
    int count = 0;
    std::string sendBuffer = "FILEPUT";
    while(fd.peek() != EOF) {
      fd >> len;
      std::string key((int)len, '\0');
      fd.read(&key[0], (int)len);
      fd >> len;
      std::string value((int)len, '\0');
      fd.read(&value[0], (int)len);
      std::string data = (char)(key.length()) 
                         + key 
                         + (char)(value.length()) 
                         + value;
      if(sendBuffer.length() + data.length() > 4000) {
        sendToServerAndGetResponse(sendBuffer, false);
        //break;
        sendBuffer = "FILEPUT";
      }
      sendBuffer += data;
      ++count;
    }
    // Do the last time.
    sendToServerAndGetResponse(sendBuffer, false);
    // Calculate time elapsed.
    auto t_end = std::chrono::high_resolution_clock::now();
    double elapsed_time_ms = 
      std::chrono::duration<double, std::milli>(t_end-t_start).count();
    std::cout << "Successfully dumped "
              << count 
              << " key-value pairs!"
              << std::endl;
    std::cout << "Time taken : "
              << (elapsed_time_ms/1000)
              << " seconds."
              << std::endl;
  }


  while(true) {
    std::cout << ">> ";
    std::string data;
    getline(std::cin, data);
    
    sendToServerAndGetResponse(data);
    
    if(data == "exit") {
      std::cout << "Exiting"
                << std::endl;
      break;
    }
  }

  // Last message
  recv(clientSd, buffer, sizeof(buffer), 0);
  std::cout << buffer << std::endl;
  close(clientSd);
  std::cout << "Connection closed" 
            << std::endl;
  return 0;    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x348, %rsp            # imm = 0x348
movq %rsi, %rbx
movl %edi, %ebp
movq 0x2d6f(%rip), %rdi      # 0x5188
callq 0x21a0
leaq 0x130(%rsp), %r14
andq $0x0, 0x8(%r14)
movw $0x2, (%r14)
movq 0x18(%rax), %rax
movq (%rax), %rax
movl (%rax), %edi
callq 0x20b0
movq %rax, %rdi
callq 0x2160
movl %eax, 0x4(%r14)
movzwl 0x2d06(%rip), %eax      # 0x5158
rolw $0x8, %ax
movw %ax, 0x2(%r14)
pushq $0x2
popq %rdi
pushq $0x1
popq %rsi
xorl %edx, %edx
callq 0x2050
movl %eax, 0x3d42(%rip)      # 0x61b0
pushq $0x10
popq %rdx
movl %eax, %edi
movq %r14, %rsi
callq 0x2120
testl %eax, %eax
js 0x26b5
movq 0x2b46(%rip), %r14      # 0x4fd0
leaq 0xbad(%rip), %rsi       # 0x303e
movq %r14, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
movl 0x3d09(%rip), %edi      # 0x61b0
leaq 0x2d02(%rip), %r15      # 0x51b0
movl $0x1000, %edx           # imm = 0x1000
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x2080
movq %r14, %rdi
movq %r15, %rsi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
cmpl $0x2, %ebp
jne 0x2788
movq 0x2af0(%rip), %rdi      # 0x4fd0
leaq 0xb70(%rip), %rsi       # 0x3057
callq 0x2150
movq %rax, %rdi
callq 0x20c0
callq 0x2030
movq %rax, 0x28(%rsp)
leaq 0x140(%rsp), %r14
movq %r14, %rdi
callq 0x2190
movq 0x8(%rbx), %rsi
pushq $0x8
popq %rdx
movq %r14, %rdi
callq 0x20f0
movq 0x140(%rsp), %rax
movq -0x18(%rax), %rax
andl $0xffffefff, 0x158(%rsp,%rax) # imm = 0xFFFFEFFF
leaq 0xb51(%rip), %rsi       # 0x308c
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x2aa4
xorl %ebp, %ebp
leaq 0x140(%rsp), %r14
leaq 0xf0(%rsp), %rbx
leaq 0x110(%rsp), %r15
leaq 0xb0(%rsp), %r12
movq %r14, %rdi
callq 0x2090
cmpl $-0x1, %eax
je 0x26c4
movq %r14, %rdi
leaq 0x7(%rsp), %rsi
callq 0x21e0
movzbl 0x7(%rsp), %esi
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x8(%rsp), %rdi
xorl %edx, %edx
callq 0x21b0
movq 0x8(%rsp), %rsi
movzbl 0x7(%rsp), %edx
movq %r14, %rdi
callq 0x21c0
movq %r14, %rdi
leaq 0x7(%rsp), %rsi
callq 0x21e0
movzbl 0x7(%rsp), %esi
leaq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x30(%rsp), %rdi
xorl %edx, %edx
callq 0x21b0
movq 0x30(%rsp), %rsi
movzbl 0x7(%rsp), %edx
movq %r14, %rdi
callq 0x21c0
movsbl 0x10(%rsp), %esi
movq %rbx, %rdi
leaq 0x8(%rsp), %rdx
callq 0x2b20
movsbl 0x38(%rsp), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2afe
movq %r12, %rdi
movq %r15, %rsi
leaq 0x30(%rsp), %rdx
callq 0x2adf
movq %r15, %rdi
callq 0x2298
movq %rbx, %rdi
callq 0x2298
movq 0xb8(%rsp), %rax
addq 0x58(%rsp), %rax
cmpq $0xfa1, %rax            # imm = 0xFA1
jb 0x2685
leaq 0x90(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x21f0
leaq 0x90(%rsp), %r13
movq %r13, %rdi
xorl %esi, %esi
callq 0x2981
movq %r13, %rdi
callq 0x2298
leaq 0x50(%rsp), %rdi
leaq 0xa0c(%rip), %rsi       # 0x308c
callq 0x2260
leaq 0x50(%rsp), %rdi
movq %r12, %rsi
callq 0x2270
incl %ebp
movq %r12, %rdi
callq 0x2298
leaq 0x30(%rsp), %rdi
callq 0x2298
leaq 0x8(%rsp), %rdi
callq 0x2298
jmp 0x256c
movl %eax, %r14d
leaq 0x963(%rip), %rsi       # 0x3022
jmp 0x2891
leaq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x21f0
leaq 0x70(%rsp), %rdi
xorl %esi, %esi
callq 0x2981
leaq 0x70(%rsp), %rdi
callq 0x2298
callq 0x2030
movq %rax, %rbx
movq 0x28d8(%rip), %rdi      # 0x4fd0
leaq 0x995(%rip), %rsi       # 0x3094
callq 0x2150
movq %rax, %rdi
movl %ebp, %esi
callq 0x2230
leaq 0x994(%rip), %rsi       # 0x30a9
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
movq 0x28a4(%rip), %rdi      # 0x4fd0
leaq 0x988(%rip), %rsi       # 0x30bb
callq 0x2150
subq 0x28(%rsp), %rbx
cvtsi2sd %rbx, %xmm0
divsd 0x8be(%rip), %xmm0      # 0x3008
divsd 0x8be(%rip), %xmm0      # 0x3010
movq %rax, %rdi
callq 0x2220
leaq 0x968(%rip), %rsi       # 0x30c9
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
leaq 0x50(%rsp), %rdi
callq 0x2298
leaq 0x140(%rsp), %rdi
callq 0x2060
leaq 0x944(%rip), %r14       # 0x30d3
movq 0x284a(%rip), %r15      # 0x4fe0
leaq 0x140(%rsp), %r12
leaq 0xd0(%rsp), %r13
pushq $0x1
popq %rbp
leaq 0x927(%rip), %rbx       # 0x30d7
movq 0x2819(%rip), %rdi      # 0x4fd0
movq %r14, %rsi
callq 0x2150
leaq 0x150(%rsp), %rax
movq %rax, 0x140(%rsp)
andq $0x0, 0x148(%rsp)
movb $0x0, 0x150(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x2040
movq %r13, %rdi
movq %r12, %rsi
callq 0x21f0
movq %r13, %rdi
movl %ebp, %esi
callq 0x2981
movq %r13, %rdi
callq 0x2298
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2b7d
testb %al, %al
jne 0x2821
movq %r12, %rdi
callq 0x2298
jmp 0x27b0
movq 0x27a8(%rip), %rdi      # 0x4fd0
leaq 0x8ad(%rip), %rsi       # 0x30dc
callq 0x2150
movq %rax, %rdi
callq 0x20c0
leaq 0x140(%rsp), %rdi
callq 0x2298
movl 0x3961(%rip), %edi      # 0x61b0
leaq 0x295a(%rip), %rbx      # 0x51b0
xorl %r14d, %r14d
movl $0x1000, %edx           # imm = 0x1000
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x2080
movq 0x2761(%rip), %rdi      # 0x4fd0
movq %rbx, %rsi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
movl 0x392b(%rip), %edi      # 0x61b0
callq 0x2280
leaq 0x853(%rip), %rsi       # 0x30e4
movq 0x2738(%rip), %rdi      # 0x4fd0
callq 0x2150
movq %rax, %rdi
callq 0x20c0
movl %r14d, %eax
addq $0x348, %rsp            # imm = 0x348
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
jmp 0x2934
jmp 0x293b
jmp 0x28c8
movq %rax, %rbx
jmp 0x2948
jmp 0x2969
jmp 0x293b
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x2298
jmp 0x2913
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x2298
jmp 0x2906
jmp 0x293b
jmp 0x292c
jmp 0x28fe
movq %rax, %rbx
jmp 0x2920
movq %rax, %rbx
leaq 0xf0(%rsp), %rdi
jmp 0x291b
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x2298
leaq 0x30(%rsp), %rdi
callq 0x2298
jmp 0x292f
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2298
jmp 0x293e
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x2298
leaq 0x140(%rsp), %rdi
callq 0x2060
jmp 0x2979
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x2298
jmp 0x296c
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0x2298
movq %rbx, %rdi
callq 0x2240