// File: 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
movq %rsp, %rbp
subq $0x490, %rsp            # imm = 0x490
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0x3c48(%rip), %rdi      # 0x6248
callq 0x20f0
movq %rax, %rdi
callq 0x22a0
movq %rax, -0x18(%rbp)
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2140
movw $0x2, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %edi
callq 0x2120
movq %rax, %rdi
callq 0x2210
movl %eax, -0x24(%rbp)
movl 0x3bd0(%rip), %eax      # 0x6220
movzwl %ax, %edi
callq 0x2040
movw %ax, -0x26(%rbp)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x2070
movl %eax, 0x4bfd(%rip)      # 0x7270
movl 0x4bf7(%rip), %edi      # 0x7270
leaq -0x28(%rbp), %rsi
movl $0x10, %edx
callq 0x21c0
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0x26bd
movq 0x3939(%rip), %rdi      # 0x5fd0
leaq 0x1984(%rip), %rsi      # 0x4022
callq 0x2200
movq %rax, %rdi
movq 0x390b(%rip), %rsi      # 0x5fb8
callq 0x2220
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x2f61
movq 0x390c(%rip), %rdi      # 0x5fd0
leaq 0x1973(%rip), %rsi      # 0x403e
callq 0x2200
movq %rax, %rdi
movq 0x38de(%rip), %rsi      # 0x5fb8
callq 0x2220
movl 0x4b8b(%rip), %edi      # 0x7270
leaq 0x3b84(%rip), %rsi      # 0x6270
movl $0x1000, %edx           # imm = 0x1000
xorl %ecx, %ecx
callq 0x20b0
movq 0x38d1(%rip), %rdi      # 0x5fd0
leaq 0x3b6a(%rip), %rsi      # 0x6270
callq 0x2200
movq %rax, %rdi
movq 0x38a3(%rip), %rsi      # 0x5fb8
callq 0x2220
cmpl $0x2, -0x8(%rbp)
jne 0x2db2
movq 0x38a5(%rip), %rdi      # 0x5fd0
leaq 0x1925(%rip), %rsi      # 0x4057
callq 0x2200
movq %rax, %rdi
movq 0x3877(%rip), %rsi      # 0x5fb8
callq 0x2220
callq 0x2030
movq %rax, -0x38(%rbp)
leaq -0x240(%rbp), %rdi
movq %rdi, -0x3e0(%rbp)
callq 0x2290
movq -0x3e0(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movl $0x8, %edx
callq 0x2170
jmp 0x277d
leaq 0xa0c(%rip), %rsi       # 0x3190
leaq -0x240(%rbp), %rdi
callq 0x2370
jmp 0x2792
movl $0x0, -0x254(%rbp)
leaq -0x279(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x23b0
movq -0x3e8(%rbp), %rdx
leaq 0x18cf(%rip), %rsi      # 0x408c
leaq -0x278(%rbp), %rdi
callq 0x30e0
jmp 0x27cb
leaq -0x279(%rbp), %rdi
callq 0x2250
leaq -0x240(%rbp), %rdi
callq 0x20c0
movl %eax, -0x3ec(%rbp)
jmp 0x27eb
movl -0x3ec(%rbp), %eax
cmpl $-0x1, %eax
je 0x2be0
leaq -0x240(%rbp), %rdi
leaq -0x24d(%rbp), %rsi
callq 0x2280
jmp 0x280f
movzbl -0x24d(%rbp), %eax
movq %rax, -0x400(%rbp)
leaq -0x2a1(%rbp), %rdi
movq %rdi, -0x3f8(%rbp)
callq 0x23b0
movq -0x400(%rbp), %rsi
movq -0x3f8(%rbp), %rcx
leaq -0x2a0(%rbp), %rdi
xorl %edx, %edx
callq 0x31c0
jmp 0x284e
leaq -0x2a1(%rbp), %rdi
callq 0x2250
xorl %eax, %eax
movl %eax, %esi
leaq -0x2a0(%rbp), %rdi
callq 0x2410
movq %rax, -0x408(%rbp)
jmp 0x2873
movq -0x408(%rbp), %rsi
movzbl -0x24d(%rbp), %eax
movl %eax, %edx
leaq -0x240(%rbp), %rdi
callq 0x22d0
jmp 0x2891
leaq -0x240(%rbp), %rdi
leaq -0x24d(%rbp), %rsi
callq 0x2280
jmp 0x28a6
movzbl -0x24d(%rbp), %eax
movq %rax, -0x418(%rbp)
leaq -0x2c9(%rbp), %rdi
movq %rdi, -0x410(%rbp)
callq 0x23b0
movq -0x418(%rbp), %rsi
movq -0x410(%rbp), %rcx
leaq -0x2c8(%rbp), %rdi
xorl %edx, %edx
callq 0x31c0
jmp 0x28e5
leaq -0x2c9(%rbp), %rdi
callq 0x2250
xorl %eax, %eax
movl %eax, %esi
leaq -0x2c8(%rbp), %rdi
callq 0x2410
movq %rax, -0x420(%rbp)
jmp 0x290a
movq -0x420(%rbp), %rsi
movzbl -0x24d(%rbp), %eax
movl %eax, %edx
leaq -0x240(%rbp), %rdi
callq 0x22d0
jmp 0x2928
leaq -0x2a0(%rbp), %rdi
movq %rdi, -0x428(%rbp)
callq 0x2330
movq -0x428(%rbp), %rdx
movsbl %al, %esi
leaq -0x330(%rbp), %rdi
callq 0x32d0
jmp 0x2953
leaq -0x2c8(%rbp), %rdi
callq 0x2330
movsbl %al, %edx
leaq -0x310(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0x3280
jmp 0x2977
leaq -0x2f0(%rbp), %rdi
leaq -0x310(%rbp), %rsi
leaq -0x2c8(%rbp), %rdx
callq 0x3230
jmp 0x2993
leaq -0x310(%rbp), %rdi
callq 0x2428
leaq -0x330(%rbp), %rdi
callq 0x2428
leaq -0x278(%rbp), %rdi
callq 0x2330
movq %rax, -0x430(%rbp)
leaq -0x2f0(%rbp), %rdi
callq 0x2330
movq %rax, %rcx
movq -0x430(%rbp), %rax
addq %rcx, %rax
cmpq $0xfa0, %rax            # imm = 0xFA0
jbe 0x2b6a
leaq -0x350(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x2100
jmp 0x29f8
leaq -0x350(%rbp), %rdi
xorl %esi, %esi
callq 0x2f80
jmp 0x2a08
leaq -0x350(%rbp), %rdi
callq 0x2428
leaq 0x1671(%rip), %rsi      # 0x408c
leaq -0x278(%rbp), %rdi
callq 0x22f0
jmp 0x2a29
jmp 0x2b6a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2da1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x279(%rbp), %rdi
callq 0x2250
jmp 0x2da1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2d95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x2a1(%rbp), %rdi
callq 0x2250
jmp 0x2d95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2bcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x2c9(%rbp), %rdi
callq 0x2250
jmp 0x2bcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2bc3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2b25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x310(%rbp), %rdi
callq 0x2428
leaq -0x330(%rbp), %rdi
callq 0x2428
jmp 0x2bc3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2bb7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x2428
jmp 0x2bb7
leaq -0x278(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x22e0
jmp 0x2b7f
movl -0x254(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x254(%rbp)
leaq -0x2f0(%rbp), %rdi
callq 0x2428
leaq -0x2c8(%rbp), %rdi
callq 0x2428
leaq -0x2a0(%rbp), %rdi
callq 0x2428
jmp 0x27d7
leaq -0x2f0(%rbp), %rdi
callq 0x2428
leaq -0x2c8(%rbp), %rdi
callq 0x2428
leaq -0x2a0(%rbp), %rdi
callq 0x2428
jmp 0x2d95
leaq -0x370(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x2100
jmp 0x2bf5
leaq -0x370(%rbp), %rdi
xorl %esi, %esi
callq 0x2f80
jmp 0x2c05
leaq -0x370(%rbp), %rdi
callq 0x2428
callq 0x2030
movq %rax, -0x378(%rbp)
leaq -0x378(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x33d0
movq %rax, -0x438(%rbp)
jmp 0x2c36
movq -0x438(%rbp), %rax
movq %rax, -0x390(%rbp)
leaq -0x388(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0x3420
jmp 0x2c59
leaq -0x388(%rbp), %rdi
callq 0x3460
movsd %xmm0, -0x440(%rbp)
jmp 0x2c6f
movsd -0x440(%rbp), %xmm0
movsd %xmm0, -0x380(%rbp)
movq 0x334a(%rip), %rdi      # 0x5fd0
leaq 0x1407(%rip), %rsi      # 0x4094
callq 0x2200
movq %rax, -0x448(%rbp)
jmp 0x2c9b
movq -0x448(%rbp), %rdi
movl -0x254(%rbp), %esi
callq 0x2390
movq %rax, -0x450(%rbp)
jmp 0x2cb6
movq -0x450(%rbp), %rdi
leaq 0x13e5(%rip), %rsi      # 0x40a9
callq 0x2200
movq %rax, -0x458(%rbp)
jmp 0x2cd2
movq -0x458(%rbp), %rdi
movq 0x32d8(%rip), %rsi      # 0x5fb8
callq 0x2220
jmp 0x2ce7
movq 0x32e2(%rip), %rdi      # 0x5fd0
leaq 0x13c6(%rip), %rsi      # 0x40bb
callq 0x2200
movq %rax, -0x460(%rbp)
jmp 0x2d03
movq -0x460(%rbp), %rdi
movsd -0x380(%rbp), %xmm0
movsd 0x12ee(%rip), %xmm1     # 0x4008
divsd %xmm1, %xmm0
callq 0x23d0
movq %rax, -0x468(%rbp)
jmp 0x2d2c
movq -0x468(%rbp), %rdi
leaq 0x138f(%rip), %rsi      # 0x40c9
callq 0x2200
movq %rax, -0x470(%rbp)
jmp 0x2d48
movq -0x470(%rbp), %rdi
movq 0x3262(%rip), %rsi      # 0x5fb8
callq 0x2220
jmp 0x2d5d
leaq -0x278(%rbp), %rdi
callq 0x2428
leaq -0x240(%rbp), %rdi
callq 0x2080
jmp 0x2db2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x2428
leaq -0x278(%rbp), %rdi
callq 0x2428
leaq -0x240(%rbp), %rdi
callq 0x2080
jmp 0x2f6d
jmp 0x2db4
movq 0x3215(%rip), %rdi      # 0x5fd0
leaq 0x1311(%rip), %rsi      # 0x40d3
callq 0x2200
leaq -0x3b0(%rbp), %rdi
movq %rdi, -0x478(%rbp)
callq 0x2300
movq -0x478(%rbp), %rsi
movq 0x31f8(%rip), %rdi      # 0x5fe0
callq 0x2060
jmp 0x2def
leaq -0x3d0(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x2100
jmp 0x2e04
leaq -0x3d0(%rbp), %rdi
movl $0x1, %esi
callq 0x2f80
jmp 0x2e17
leaq -0x3d0(%rbp), %rdi
callq 0x2428
leaq 0x12ad(%rip), %rsi      # 0x40d7
leaq -0x3b0(%rbp), %rdi
callq 0x3480
movb %al, -0x479(%rbp)
jmp 0x2e3e
movb -0x479(%rbp), %al
testb $0x1, %al
jne 0x2e4a
jmp 0x2ebb
movq 0x317f(%rip), %rdi      # 0x5fd0
leaq 0x1284(%rip), %rsi      # 0x40dc
callq 0x2200
movq %rax, -0x488(%rbp)
jmp 0x2e66
movq -0x488(%rbp), %rdi
movq 0x3144(%rip), %rsi      # 0x5fb8
callq 0x2220
jmp 0x2e7b
movl $0x5, -0x3d4(%rbp)
jmp 0x2ec5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0x2ee4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x2428
jmp 0x2ee4
movl $0x0, -0x3d4(%rbp)
leaq -0x3b0(%rbp), %rdi
callq 0x2428
movl -0x3d4(%rbp), %eax
testl %eax, %eax
je 0x2edf
jmp 0x2edd
jmp 0x2ef2
jmp 0x2db4
leaq -0x3b0(%rbp), %rdi
callq 0x2428
jmp 0x2f6d
movl 0x4378(%rip), %edi      # 0x7270
leaq 0x3371(%rip), %rsi      # 0x6270
movl $0x1000, %edx           # imm = 0x1000
xorl %ecx, %ecx
callq 0x20b0
movq 0x30be(%rip), %rdi      # 0x5fd0
leaq 0x3357(%rip), %rsi      # 0x6270
callq 0x2200
movq %rax, %rdi
movq 0x3090(%rip), %rsi      # 0x5fb8
callq 0x2220
movl 0x433d(%rip), %edi      # 0x7270
callq 0x23f0
movq 0x3091(%rip), %rdi      # 0x5fd0
leaq 0x119e(%rip), %rsi      # 0x40e4
callq 0x2200
movq %rax, %rdi
movq 0x3063(%rip), %rsi      # 0x5fb8
callq 0x2220
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x490, %rsp            # imm = 0x490
popq %rbp
retq
movq -0x248(%rbp), %rdi
callq 0x23a0
nopl (%rax)