// File: Lartu[P]coraldb/source/coraldb.cpp
// Function: handle_socket(int)
void handle_socket(int new_socket_fd)
{
    // TODO add alarm with timeout https://stackoverflow.com/questions/9163308/how-to-use-timeouts-with-read-on-a-socket-in-c-on-unix/9163476
    std::string str_buffer = "";
    char buffer[1024];
    size_t bytes_read;
    bool request_read_end = false;
    bool last_char_was_cr = false;
    while ((bytes_read = recv(new_socket_fd, buffer, sizeof(buffer), 0)) > 0)
    {
        for (unsigned int i = 0; i < bytes_read; ++i)
        {
            // \r\n terminates the message.
            if (buffer[i] == '\r')
            {
                last_char_was_cr = true;
            }
            else if (buffer[i] == '\n' && last_char_was_cr)
            {
                request_read_end = true;
                break;
            }
            else
            {
                if (last_char_was_cr)
                {
                    // If we found a CR but it wasn't a CRLF, add the CR to the buffer.
                    str_buffer += '\r';
                    last_char_was_cr = false;
                }
                str_buffer += buffer[i];
            }
        }
        if (request_read_end)
            break;
    }
    int retcode = execute_command(str_buffer, new_socket_fd);
    if (retcode == 1)
    {
        send(new_socket_fd, ERROR_MSG, strlen(ERROR_MSG), 0);
    }
    else if (retcode == 0)
    {
        send(new_socket_fd, OK_MSG, strlen(OK_MSG), 0);
    }
    else if (retcode == 3)
    {
        send(new_socket_fd, KEY_ERROR_MSG, strlen(KEY_ERROR_MSG), 0);
    }
    // retcode 2 means "don't send anything"
    shutdown(new_socket_fd, SHUT_RDWR);
    recv(new_socket_fd, buffer, sizeof(buffer), 0);
    close(new_socket_fd);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4a0, %rsp            # imm = 0x4A0
movl %edi, -0x4(%rbp)
leaq -0x29(%rbp), %rdi
movq %rdi, -0x460(%rbp)
callq 0x3510
movq -0x460(%rbp), %rdx
leaq 0x582b(%rip), %rsi      # 0xb197
leaq -0x28(%rbp), %rdi
callq 0x3410
jmp 0x5977
leaq -0x29(%rbp), %rdi
callq 0x3330
movb $0x0, -0x449(%rbp)
movb $0x0, -0x44a(%rbp)
movl -0x4(%rbp), %edi
leaq -0x440(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
xorl %ecx, %ecx
callq 0x3120
movq %rax, -0x468(%rbp)
jmp 0x59ad
movq -0x468(%rbp), %rax
movq %rax, -0x448(%rbp)
cmpq $0x0, %rax
jbe 0x5abd
movl $0x0, -0x450(%rbp)
movl -0x450(%rbp), %eax
cmpq -0x448(%rbp), %rax
jae 0x5aad
movl -0x450(%rbp), %eax
movsbl -0x440(%rbp,%rax), %eax
cmpl $0xd, %eax
jne 0x5a35
movb $0x1, -0x44a(%rbp)
jmp 0x5a97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x29(%rbp), %rdi
callq 0x3330
jmp 0x5be5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x3578
jmp 0x5be5
movl -0x450(%rbp), %eax
movsbl -0x440(%rbp,%rax), %eax
cmpl $0xa, %eax
jne 0x5a5a
testb $0x1, -0x44a(%rbp)
je 0x5a5a
movb $0x1, -0x449(%rbp)
jmp 0x5aad
testb $0x1, -0x44a(%rbp)
je 0x5a7a
leaq -0x28(%rbp), %rdi
movl $0xd, %esi
callq 0x3220
jmp 0x5a73
movb $0x0, -0x44a(%rbp)
movl -0x450(%rbp), %eax
movsbl -0x440(%rbp,%rax), %esi
leaq -0x28(%rbp), %rdi
callq 0x3220
jmp 0x5a93
jmp 0x5a95
jmp 0x5a97
jmp 0x5a99
movl -0x450(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x450(%rbp)
jmp 0x59cf
testb $0x1, -0x449(%rbp)
je 0x5ab8
jmp 0x5abd
jmp 0x598e
movl -0x4(%rbp), %esi
leaq -0x28(%rbp), %rdi
callq 0x3ca0
movl %eax, -0x46c(%rbp)
jmp 0x5ad1
movl -0x46c(%rbp), %eax
movl %eax, -0x454(%rbp)
cmpl $0x1, -0x454(%rbp)
jne 0x5b20
movl -0x4(%rbp), %eax
movl %eax, -0x47c(%rbp)
leaq 0xb7ff(%rip), %rdi      # 0x112f5
movq %rdi, -0x478(%rbp)
callq 0x3180
movl -0x47c(%rbp), %edi
movq -0x478(%rbp), %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x31d0
jmp 0x5b1b
jmp 0x5ba4
cmpl $0x0, -0x454(%rbp)
jne 0x5b60
movl -0x4(%rbp), %eax
movl %eax, -0x48c(%rbp)
leaq 0xb7c5(%rip), %rdi      # 0x112fe
movq %rdi, -0x488(%rbp)
callq 0x3180
movl -0x48c(%rbp), %edi
movq -0x488(%rbp), %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x31d0
jmp 0x5b5e
jmp 0x5ba2
cmpl $0x3, -0x454(%rbp)
jne 0x5ba0
movl -0x4(%rbp), %eax
movl %eax, -0x49c(%rbp)
leaq 0xb76f(%rip), %rdi      # 0x112e8
movq %rdi, -0x498(%rbp)
callq 0x3180
movl -0x49c(%rbp), %edi
movq -0x498(%rbp), %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x31d0
jmp 0x5b9e
jmp 0x5ba0
jmp 0x5ba2
jmp 0x5ba4
movl -0x4(%rbp), %edi
movl $0x2, %esi
callq 0x3420
movl -0x4(%rbp), %edi
leaq -0x440(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
xorl %ecx, %ecx
callq 0x3120
jmp 0x5bc9
movl -0x4(%rbp), %edi
callq 0x3550
jmp 0x5bd3
leaq -0x28(%rbp), %rdi
callq 0x3578
addq $0x4a0, %rsp            # imm = 0x4A0
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x3500
nop