// File: /workspace/github_cpp_makefile_star2_O3/AraKhachatryan[P]messenger/client.cpp
// Function: send_thread(void*)
void * send_thread( void * arg )
{
    int socket_desc = *(int*)arg;

    char client_name[50];
    std::vector<std::string> dest_names;
    std::string message_info;
    std::string message;

    char input[392];
    char input_encoded[512];

    bzero(client_name, sizeof(client_name));

    std::cout << "Write your name: " << terminal::TEXT_BOLD << terminal::TEXTCOLOR_CYAN;
    std::cin.getline(client_name, 50);
    std::cout << terminal::RESET_ALL;

	send(socket_desc, (char*)&client_name, sizeof(client_name), 0);

	std::cout << "Private message pattern: @<Destination name>: <message>" << std::endl;
	std::cout << "Public message typed as is: <message>" << std::endl;
	std::cout << "Write your first message !!!" << std::endl << std::endl;

    while(1)
    {
        // clear all data buffers
        bzero(input, sizeof(input));
        bzero(input_encoded, sizeof(input_encoded));
        dest_names.clear();
        message_info.clear();
        message.clear();

        std::cin.getline(input, sizeof(input));


        // Erase input from terminal   ////////////////////////////////////////
        int input_size = std::cin.gcount();
        struct winsize w;
        ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
        int erase_line_count = 0;
        if( (input_size % w.ws_col) != 0 )
        {
            erase_line_count = (int)(input_size / w.ws_col) + 1;
        } else {
            erase_line_count = (int)(input_size / w.ws_col);
        }
        while( erase_line_count-- != 0 )
        {
            std::cout << terminal::Cursor_Previous_Line() << terminal::Erase_Line();
        }
        ///////////////////////////////////////////////////////////////////////


        // If input is empty (Enter key is pressed) do nothing
        if ( input_size == 1 )
        {
            continue;
        }


        encode_message(input, input_encoded, sizeof(input_encoded));
        //print_encoded_message(input_encoded, sizeof(input_encoded));

        send(socket_desc,(char*)&input_encoded, sizeof(input_encoded), 0);

        // decoding for input formatting in terminal
        decode_message(input_encoded, sizeof(input_encoded), dest_names, message_info, message);


        // Formatting input (encoded -> decoded input message)   ////////////////////
        // Private message is send
        if ( !dest_names.empty() )
        {
            std::cout << terminal::TEXT_BOLD << terminal::TEXTCOLOR_BLUE;

            for( auto it = dest_names.begin(); it != dest_names.end(); ++it )
            {
                std::cout << *it;
                if ( *it != dest_names.back() )
                {
                    std::cout << ", ";
                }
            }

            std::cout << terminal::RESET_ALL << "<- " << terminal::TEXT_BOLD << terminal::TEXTCOLOR_YELLOW
                        << message << terminal::RESET_ALL << std::endl;

        // Public message is send (if no dest_names)
        } else {
            std::cout << terminal::TEXT_BOLD << terminal::TEXTCOLOR_YELLOW
                        << message << terminal::RESET_ALL << std::endl;

        }
        ///////////////////////////////////////////////////////////////////////



    } // End while()

    pthread_exit(NULL);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x478, %rsp            # imm = 0x478
movl (%rdi), %eax
movl %eax, 0xc(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0x98(%rsp), %r14
movq %r14, -0x10(%r14)
movq %rax, -0x8(%r14)
movb %al, (%r14)
leaq 0x38(%rsp), %r12
movq %r12, -0x10(%r12)
movq %rax, -0x8(%r12)
movb %al, (%r12)
movaps %xmm0, 0xb0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movw $0x0, 0xe0(%rsp)
movq 0x4950(%rip), %rbx      # 0x6fc8
leaq 0x29f6(%rip), %rsi      # 0x5075
movl $0x11, %edx
movq %rbx, %rdi
callq 0x21e0
movb 0x4ade(%rip), %al       # 0x7170
cmpb $0x1, %al
jne 0x26dc
movq 0x492b(%rip), %rdi      # 0x6fc8
leaq 0x2ad6(%rip), %rsi      # 0x517a
movl $0x2, %edx
callq 0x21e0
movq 0x4913(%rip), %rdi      # 0x6fc8
movl $0x1, %esi
callq 0x2250
movq %rax, %rbx
leaq 0x2ab4(%rip), %rsi      # 0x517d
movl $0x1, %edx
movq %rax, %rdi
callq 0x21e0
movb 0x4a94(%rip), %al       # 0x7170
testb $0x1, %al
je 0x2715
leaq 0x2a93(%rip), %rsi      # 0x517a
movl $0x2, %edx
movq %rbx, %rdi
callq 0x21e0
movq %rbx, %rdi
movl $0x24, %esi
callq 0x2250
leaq 0x2a75(%rip), %rsi      # 0x517d
movl $0x1, %edx
movq %rax, %rdi
callq 0x21e0
movq 0x48bc(%rip), %rdi      # 0x6fd8
movq (%rdi), %rax
addq -0x18(%rax), %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %ecx
movq 0x48a1(%rip), %rdi      # 0x6fd8
leaq 0xb0(%rsp), %rsi
movl $0x32, %edx
callq 0x22a0
cmpb $0x1, 0x4a20(%rip)      # 0x7170
jne 0x278c
movq 0x486f(%rip), %rdi      # 0x6fc8
leaq 0x2a1a(%rip), %rsi      # 0x517a
movl $0x2, %edx
callq 0x21e0
movq 0x4857(%rip), %rdi      # 0x6fc8
xorl %esi, %esi
callq 0x2250
leaq 0x29fe(%rip), %rsi      # 0x517d
movl $0x1, %edx
movq %rax, %rdi
callq 0x21e0
leaq 0xb0(%rsp), %rsi
movl $0x32, %edx
movl 0xc(%rsp), %edi
xorl %ecx, %ecx
callq 0x20d0
movq 0x481d(%rip), %rdi      # 0x6fc8
leaq 0x28d5(%rip), %rsi      # 0x5087
movl $0x37, %edx
callq 0x21e0
movq 0x4805(%rip), %rdi      # 0x6fc8
callq 0x20c0
movq 0x47f9(%rip), %rdi      # 0x6fc8
leaq 0x28e9(%rip), %rsi      # 0x50bf
movl $0x25, %edx
callq 0x21e0
movq 0x47e1(%rip), %rdi      # 0x6fc8
callq 0x20c0
movq 0x47d5(%rip), %rdi      # 0x6fc8
leaq 0x28eb(%rip), %rsi      # 0x50e5
movl $0x1c, %edx
callq 0x21e0
movq 0x47bd(%rip), %r15      # 0x6fc8
movq %r15, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x20c0
leaq 0x68(%rsp), %rbx
leaq 0x48(%rsp), %r12
movl $0x188, %edx            # imm = 0x188
leaq 0x2f0(%rsp), %rdi
xorl %esi, %esi
callq 0x2100
movl $0x200, %edx            # imm = 0x200
leaq 0xf0(%rsp), %rdi
xorl %esi, %esi
callq 0x2100
movq 0x10(%rsp), %r14
movq 0x18(%rsp), %r13
cmpq %r14, %r13
je 0x288a
leaq 0x10(%r14), %rbp
movq -0x10(%rbp), %rdi
cmpq %rdi, %rbp
je 0x2875
movq (%rbp), %rsi
incq %rsi
callq 0x21c0
leaq 0x20(%rbp), %rax
addq $0x10, %rbp
cmpq %r13, %rbp
movq %rax, %rbp
jne 0x2860
movq %r14, 0x18(%rsp)
xorl %ecx, %ecx
movq %rcx, 0x90(%rsp)
movq 0x88(%rsp), %rax
movb %cl, (%rax)
movq %rcx, 0x30(%rsp)
movq 0x28(%rsp), %rax
movb %cl, (%rax)
movq 0x4727(%rip), %r14      # 0x6fd8
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %ecx
movl $0x188, %edx            # imm = 0x188
movq %r14, %rdi
leaq 0x2f0(%rsp), %rsi
callq 0x22a0
movl 0x8(%r14), %r13d
movl $0x5413, %esi           # imm = 0x5413
movl $0x1, %edi
leaq 0xa8(%rsp), %rdx
xorl %eax, %eax
callq 0x2210
movzwl 0xaa(%rsp), %ecx
movl %r13d, %eax
cltd
idivl %ecx
xorl %ebp, %ebp
testl %edx, %edx
setne %bpl
addl %eax, %ebp
je 0x2991
movq %rbx, %rdi
movl $0x1, %esi
callq 0x3601
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
movq %r15, %rdi
callq 0x21e0
movq %rax, %r14
movq %r12, %rdi
movl $0x2, %esi
callq 0x36d3
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdx
movq %r14, %rdi
callq 0x21e0
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x2971
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x298d
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x21c0
decl %ebp
jne 0x2914
cmpl $0x1, %r13d
je 0x2825
movl $0x200, %edx            # imm = 0x200
leaq 0x2f0(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x389c
movl $0x200, %edx            # imm = 0x200
movl 0xc(%rsp), %edi
leaq 0xf0(%rsp), %rsi
xorl %ecx, %ecx
callq 0x20d0
movl $0x200, %esi            # imm = 0x200
leaq 0xf0(%rsp), %rdi
leaq 0x10(%rsp), %rdx
leaq 0x88(%rsp), %rcx
leaq 0x28(%rsp), %r8
callq 0x3b22
movq 0x10(%rsp), %rcx
movb 0x4774(%rip), %al       # 0x7170
cmpq 0x18(%rsp), %rcx
je 0x2c2c
movq %r15, %r13
testb %al, %al
je 0x2a4c
movl $0x2, %edx
movq %r15, %rdi
leaq 0x275d(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r15, %rdi
movl $0x1, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x273c(%rip), %rsi      # 0x517d
callq 0x21e0
movb 0x4724(%rip), %al       # 0x7170
testb $0x1, %al
je 0x2a85
movl $0x2, %edx
movq %r13, %rdi
leaq 0x271b(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
movl $0x22, %esi
callq 0x2250
movl $0x1, %edx
movq %rax, %rdi
leaq 0x26fd(%rip), %rsi      # 0x517d
callq 0x21e0
movq 0x10(%rsp), %r14
cmpq 0x18(%rsp), %r14
je 0x2ae6
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq %r15, %rdi
callq 0x21e0
movq 0x18(%rsp), %r13
movq 0x8(%r14), %rdx
cmpq -0x18(%r13), %rdx
jne 0x2ac4
testq %rdx, %rdx
je 0x2add
movq -0x20(%r13), %rsi
movq (%r14), %rdi
callq 0x21d0
testl %eax, %eax
je 0x2add
movl $0x2, %edx
movq %r15, %rdi
leaq 0x262f(%rip), %rsi      # 0x5102
callq 0x21e0
movq 0x18(%rsp), %r13
addq $0x20, %r14
cmpq %r13, %r14
jne 0x2a91
cmpb $0x1, 0x4683(%rip)      # 0x7170
movq %r15, %r13
jne 0x2b27
movl $0x2, %edx
movq %r15, %rdi
leaq 0x2679(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r15, %rdi
xorl %esi, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x265b(%rip), %rsi      # 0x517d
callq 0x21e0
movl $0x3, %edx
movq %r13, %rdi
leaq 0x25cf(%rip), %rsi      # 0x5105
callq 0x21e0
movb 0x462f(%rip), %al       # 0x7170
cmpb $0x1, %al
jne 0x2b83
movl $0x2, %edx
movq %r13, %rdi
leaq 0x2626(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
movl $0x1, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2605(%rip), %rsi      # 0x517d
callq 0x21e0
movb 0x45ed(%rip), %al       # 0x7170
testb $0x1, %al
je 0x2bbf
movl $0x2, %edx
movq %r13, %rdi
leaq 0x25e4(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
movl $0x21, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x25c3(%rip), %rsi      # 0x517d
callq 0x21e0
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq %r13, %rdi
callq 0x21e0
movq %rax, %r13
cmpb $0x1, 0x4595(%rip)      # 0x7170
jne 0x2c12
movl $0x2, %edx
movq %r13, %rdi
leaq 0x258e(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
xorl %esi, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2570(%rip), %rsi      # 0x517d
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x2190
jmp 0x2d15
movq %r15, %r13
testb %al, %al
je 0x2c71
movl $0x2, %edx
movq %r15, %rdi
leaq 0x2538(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r15, %rdi
movl $0x1, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2517(%rip), %rsi      # 0x517d
callq 0x21e0
movb 0x44ff(%rip), %al       # 0x7170
testb $0x1, %al
je 0x2cad
movl $0x2, %edx
movq %r13, %rdi
leaq 0x24f6(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
movl $0x21, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x24d5(%rip), %rsi      # 0x517d
callq 0x21e0
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq %r13, %rdi
callq 0x21e0
movq %rax, %r13
cmpb $0x1, 0x44a7(%rip)      # 0x7170
jne 0x2d00
movl $0x2, %edx
movq %r13, %rdi
leaq 0x24a0(%rip), %rsi      # 0x517a
callq 0x21e0
movq %r13, %rdi
xorl %esi, %esi
callq 0x2250
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2482(%rip), %rsi      # 0x517d
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
jmp 0x2825
jmp 0x2d33
jmp 0x2d33
jmp 0x2d33
movq %rax, %rbx
jmp 0x2d7a
jmp 0x2d3a
movq %rax, %rbx
jmp 0x2d5e
movq %rax, %rbx
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x2d5e
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x2d7a
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x21c0
leaq 0x98(%rsp), %r14
leaq 0x38(%rsp), %r12
jmp 0x2d8c
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x2da3
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x88(%rsp), %rdi
cmpq %r14, %rdi
je 0x2dc0
movq 0x98(%rsp), %rsi
incq %rsi
callq 0x21c0
leaq 0x10(%rsp), %rdi
callq 0x37a6
movq %rbx, %rdi
callq 0x2260