// File: /workspace/github_cpp_makefile_star2_O2/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), %ebx
andq $0x0, 0x20(%rsp)
leaq 0x60(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorps %xmm0, %xmm0
xorl %ecx, %ecx
movb %cl, (%rax)
leaq 0x40(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movaps %xmm0, 0x10(%rsp)
movb %cl, (%rax)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x90(%rsp)
andw $0x0, 0xa0(%rsp)
movq 0x3a16(%rip), %rdi      # 0x5fc8
leaq 0x1abc(%rip), %rsi      # 0x4075
callq 0x21c0
pushq $0x1
popq %rsi
movq %rax, %rdi
callq 0x2b4e
pushq $0x24
popq %rsi
movq %rax, %rdi
callq 0x2b4e
movq 0x39fd(%rip), %rdi      # 0x5fd8
leaq 0x70(%rsp), %rsi
pushq $0x32
popq %rdx
callq 0x2080
movq 0x39d9(%rip), %rdi      # 0x5fc8
xorl %esi, %esi
callq 0x2b4e
leaq 0x70(%rsp), %rsi
pushq $0x32
popq %rdx
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x2110
movq 0x39ba(%rip), %rdi      # 0x5fc8
leaq 0x1a72(%rip), %rsi      # 0x4087
callq 0x21c0
movq %rax, %rdi
callq 0x2100
movq 0x399f(%rip), %rdi      # 0x5fc8
leaq 0x1a8f(%rip), %rsi      # 0x40bf
callq 0x21c0
movq %rax, %rdi
callq 0x2100
movq 0x3984(%rip), %r15      # 0x5fc8
leaq 0x1a9a(%rip), %rsi      # 0x40e5
movq %r15, %rdi
callq 0x21c0
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x2100
movl %ebx, 0x8(%rsp)
pushq $0x1
popq %rbp
leaq 0xd0(%rsp), %rbx
leaq 0xb0(%rsp), %r12
movl $0x188, %edx            # imm = 0x188
leaq 0x2f0(%rsp), %r13
movq %r13, %rdi
xorl %esi, %esi
callq 0x2130
movl $0x200, %edx            # imm = 0x200
leaq 0xf0(%rsp), %rdi
xorl %esi, %esi
callq 0x2130
leaq 0x10(%rsp), %rdi
callq 0x2b84
andq $0x0, 0x58(%rsp)
movq 0x50(%rsp), %rax
xorl %ecx, %ecx
movb %cl, (%rax)
andq $0x0, 0x38(%rsp)
movq 0x30(%rsp), %rax
movb %cl, (%rax)
movl $0x188, %edx            # imm = 0x188
movq 0x3901(%rip), %r14      # 0x5fd8
movq %r14, %rdi
movq %r13, %rsi
callq 0x2080
movl 0x8(%r14), %r14d
movl $0x5413, %esi           # imm = 0x5413
movl %ebp, %edi
leaq 0x28(%rsp), %rdx
xorl %eax, %eax
callq 0x2240
movzwl 0x2a(%rsp), %ecx
movl %r14d, 0xc(%rsp)
movl %r14d, %eax
cltd
idivl %ecx
movl %eax, %r14d
cmpl $0x1, %edx
sbbl $-0x1, %r14d
subl $0x1, %r14d
jb 0x2759
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2b8c
movq %r15, %rdi
movq %rbx, %rsi
callq 0x21a0
movq %rax, %r13
movq %r12, %rdi
pushq $0x2
popq %rsi
callq 0x2c2b
movq %r13, %rdi
movq %r12, %rsi
callq 0x21a0
movq %r12, %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x20f0
jmp 0x2713
cmpl $0x1, 0xc(%rsp)
je 0x267a
movl $0x200, %edx            # imm = 0x200
leaq 0x2f0(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x2e90
movl $0x200, %edx            # imm = 0x200
movl 0x8(%rsp), %edi
leaq 0xf0(%rsp), %rsi
xorl %ecx, %ecx
callq 0x2110
movl $0x200, %esi            # imm = 0x200
leaq 0xf0(%rsp), %rdi
leaq 0x10(%rsp), %rdx
leaq 0x50(%rsp), %rcx
leaq 0x30(%rsp), %r8
callq 0x30c9
movq 0x10(%rsp), %rcx
movq %r15, %rax
cmpq 0x18(%rsp), %rcx
je 0x2835
movq %r15, %rdi
movl %ebp, %esi
callq 0x2b4e
movq %rax, %rdi
pushq $0x22
popq %rsi
callq 0x2b4e
movq 0x10(%rsp), %r14
cmpq 0x18(%rsp), %r14
je 0x281c
movq %r15, %rdi
movq %r14, %rsi
callq 0x21a0
movq 0x18(%rsp), %rsi
addq $-0x20, %rsi
movq %r14, %rdi
callq 0x2cca
testb %al, %al
je 0x2816
movq %r15, %rdi
leaq 0x18f1(%rip), %rsi      # 0x4102
callq 0x21c0
addq $0x20, %r14
jmp 0x27e0
movq %r15, %rdi
xorl %esi, %esi
callq 0x2b4e
movq %rax, %rdi
leaq 0x18d5(%rip), %rsi      # 0x4105
callq 0x21c0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2b4e
movq %rax, %rdi
pushq $0x21
popq %rsi
callq 0x2b4e
movq %rax, %rdi
leaq 0x30(%rsp), %rsi
callq 0x21a0
movq %rax, %rdi
xorl %esi, %esi
callq 0x2b4e
movq %rax, %rdi
callq 0x2100
jmp 0x267a
jmp 0x289c
jmp 0x289c
jmp 0x289c
jmp 0x289c
jmp 0x2878
movq %rax, %rbx
jmp 0x288d
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x20f0
leaq 0xd0(%rsp), %rdi
callq 0x20f0
jmp 0x289f
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x20f0
leaq 0x50(%rsp), %rdi
callq 0x20f0
leaq 0x10(%rsp), %rdi
callq 0x2cd4
movq %rbx, %rdi
callq 0x2280