// File: /workspace/github_cpp_makefile_star2_O1/JohnPapad[P]Mini-Search-Engine/minisearch.cpp
// Function: print_k_docs(char**, char**, unsigned int*, unsigned int*, posting_list**, unsigned int, unsigned int, double, unsigned int, unsigned int, double, double, unsigned int)
void print_k_docs(char ** docs, char ** queries, unsigned int * unq_doc_ids, unsigned int * docs_word_counter, posting_list ** pl_array,
     unsigned int unq_doc_ids_size, unsigned int nqs, double avgdl, unsigned int ndocs, unsigned int K, double k1,
     double b, unsigned int lwidth)
{
    double * unq_docs_relev_score = (double *) malloc(unq_doc_ids_size * sizeof(double)); //stores each unique doc's score

    for(unsigned int i = 0; i < unq_doc_ids_size; i++)
    {//for each unique doc
        double total_relev_score = 0.0 ;
        for(unsigned int j = 0 ; j < nqs; j++)
        {//for each query
            posting_list * query_pl_ptr = pl_array[j];
            unsigned int term_freq, doc_freq ;

            if(query_pl_ptr == NULL)
            {
                term_freq = 0;
                doc_freq = 0;
            }
            else
            {
                term_freq = query_pl_ptr->get_term_freq(unq_doc_ids[i]);
                doc_freq = query_pl_ptr->get_size();
            }

            total_relev_score += get_relevance_score(term_freq, doc_freq, avgdl, docs_word_counter[unq_doc_ids[i]], ndocs, k1, b);
        }

        unq_docs_relev_score[i] = total_relev_score;
    }


    //sorting unique doc ids and their corresponding relevance scores at the same time based on scores' values
    for(unsigned int i = 0; i < unq_doc_ids_size; i++)
    {
        for(unsigned int j = i+1; j < unq_doc_ids_size; j++)
        {
            if(unq_docs_relev_score[i] < unq_docs_relev_score[j])
            {
                double temp = unq_docs_relev_score[i];
                unsigned int temp2 = unq_doc_ids[i];

                unq_docs_relev_score[i] = unq_docs_relev_score[j];
                unq_docs_relev_score[j] = temp;

                unq_doc_ids[i] = unq_doc_ids[j];
                unq_doc_ids[j] = temp2;
            }
        }
    }

    for(unsigned int i = 0 ; i < unq_doc_ids_size; i++)
    {//for each unique doc
        if (i == K) //print only the top K docs
        {
            break;
        }

        //calculating the width for doc's info (score, doc id, index, etc )
        unsigned int doc_id_len = get_number_of_digits(int(unq_doc_ids[i]));
        unsigned int i_len = get_number_of_digits(int(i));
        double integral;
        modf(unq_docs_relev_score[i], &integral);
        unsigned int score_dec_part_len = get_number_of_digits(int(integral));
        unsigned int init_llen= doc_id_len + i_len + score_dec_part_len + 8 + 5 + 1;
        if(unq_docs_relev_score[i] < 0)
        {
            init_llen++;
        }

        char * doc = docs[unq_doc_ids[i]];
        char * doc_cpy = (char *)malloc((strlen(doc) + 1) * sizeof(char));
        strcpy(doc_cpy, doc);
        char *rest_line;
        char *curr_word = strtok_r(doc_cpy, " \t", &rest_line);

        int ** underline_info = NULL; //indicates which words needs underlining
        int underline_info_size = 0;
        unsigned int curr_llen = init_llen; //indicates how nuch of terminal's usefull printing space is occupied at every moment
        bool next_word = 0;

        cout.precision(5);
        cout<<i+1<<".( "<<unq_doc_ids[i]<<") ["<<fixed<< unq_docs_relev_score[i]  <<"] ";

            while(curr_word != NULL)
            {
                if ((strlen(curr_word) > (lwidth - init_llen)) && (curr_llen != lwidth))
                {//if word's length is bigger than terminal's printing space
                    unsigned int init_curr_llen = curr_llen;
                    bool new_line = 0 ;
                    bool word_exist = search_doc_word_into_queries(curr_word, queries, nqs);

                    for(unsigned int i = 0; i < strlen(curr_word); i++)
                    {//printing word letter by letter - word will be seperated in different lines
                        if ((curr_llen + 1) > lwidth)
                        {
                            if (word_exist == 1)
                            {
                                if (new_line == 0)
                                {//if word has not yet been seperated in different lines
                                    underline_info_size += 2;
                                    underline_info = reallocate_underline_info(underline_info, underline_info_size, init_curr_llen, lwidth);
                                }
                                else
                                {
                                    underline_info_size = 2;
                                    underline_info = reallocate_underline_info(underline_info, underline_info_size, init_llen, lwidth);
                                }

                                underline(init_llen, curr_llen, underline_info, underline_info_size, 0);
                            }
                            else
                            {
                                if (underline_info_size > 0)
                                {
                                    underline(init_llen, curr_llen, underline_info, underline_info_size, 0);
                                }
                                else
                                {
                                    init_newline(init_llen, curr_llen);
                                }
                            }

                            new_line = 1;
                        }

                        curr_llen++;
                        cout<<curr_word[i];
                    }

                    if (word_exist == 1)
                    {
                        underline_info_size = 2;
                        underline_info = reallocate_underline_info(underline_info, underline_info_size, init_llen, curr_llen);
                    }

                    bool exit = manage_whitespace(rest_line, lwidth, init_llen, curr_llen, underline_info, underline_info_size);
                    if(exit == 1)
                    {
                        break;
                    }

                    next_word = 1;
                }
                else if (strlen(curr_word) <= (lwidth - curr_llen))
                {//if word can fit in remaining terminal's line space
                    bool word_exist = search_doc_word_into_queries(curr_word, queries, nqs);
                    if (word_exist == 1)
                    {
                        underline_info_size += 2;
                        underline_info = reallocate_underline_info(underline_info, underline_info_size, curr_llen, curr_llen + strlen(curr_word));
                    }

                    cout<<curr_word;
                    curr_llen += strlen(curr_word);
                    next_word = 1;

                    bool exit = manage_whitespace(rest_line, lwidth, init_llen, curr_llen, underline_info, underline_info_size);
                    if (exit == 1)
                    {
                        break;
                    }
                }
                else
                {//if word can not fit in remaining terminal's line space
                    next_word = 0;

                    if (underline_info_size > 0)
                    {
                        underline(init_llen, curr_llen, underline_info, underline_info_size, 0);
                    }
                    else
                    {
                        init_newline(init_llen, curr_llen);
                    }
                }

                if(next_word == 1)
                {//take next word for printing
                    curr_word = strtok_r(rest_line, " \t", &rest_line);
                }
            }

            cout<<endl;
            for(unsigned int i = 0; i < lwidth; i++)
            {
                cout<<"=";
            }
            cout<<endl;

            free(underline_info);
            free(doc_cpy);
    }

    free(unq_docs_relev_score);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movsd %xmm2, 0x50(%rsp)
movsd %xmm1, 0x48(%rsp)
movsd %xmm0, 0x28(%rsp)
movl %r9d, %ebx
movq %r8, 0x70(%rsp)
movq %rcx, %r15
movq %rdx, %rbp
movq %rsi, %r13
movq %rdi, 0x78(%rsp)
movl 0xe0(%rsp), %r14d
movl %r9d, %r12d
leaq (,%r12,8), %rdi
callq 0x2170
movq %rax, 0x40(%rsp)
movq %rbx, 0x38(%rsp)
testl %ebx, %ebx
movq %rbp, 0x30(%rsp)
movq %r13, 0x60(%rsp)
je 0x3a6c
movsd 0x1955(%rip), %xmm0     # 0x5200
movsd 0x48(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x88(%rsp)
movsd 0x50(%rsp), %xmm3
subsd %xmm3, %xmm0
movsd %xmm0, 0x68(%rsp)
movl 0xd0(%rsp), %r13d
xorl %r14d, %r14d
movq %r12, 0x80(%rsp)
xorpd %xmm0, %xmm0
cmpl $0x0, 0xd0(%rsp)
je 0x39d7
xorl %ebx, %ebx
movsd %xmm0, 0x10(%rsp)
movq 0x70(%rsp), %rax
movq (%rax,%rbx,8), %r12
testq %r12, %r12
je 0x3931
movl (%rbp,%r14,4), %esi
movq %r12, %rdi
callq 0x47a4
movl %eax, %ebp
movq %r12, %rdi
callq 0x4674
movl %ebp, %ecx
movq 0x30(%rsp), %rbp
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
jmp 0x3937
xorl %eax, %eax
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
movl (%rbp,%r14,4), %ecx
movl (%r15,%rcx,4), %r12d
movl 0xd8(%rsp), %ecx
subl %eax, %ecx
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
movsd 0x1899(%rip), %xmm2     # 0x51f8
addsd %xmm2, %xmm0
movl %eax, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x2070
movsd 0x88(%rsp), %xmm1
movsd 0x20(%rsp), %xmm5
mulsd %xmm5, %xmm1
xorps %xmm2, %xmm2
cvtsi2sd %r12, %xmm2
divsd 0x28(%rsp), %xmm2
movsd 0x50(%rsp), %xmm3
mulsd %xmm3, %xmm2
addsd 0x68(%rsp), %xmm2
movsd 0x48(%rsp), %xmm4
mulsd %xmm4, %xmm2
addsd %xmm5, %xmm2
divsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
addsd %xmm1, %xmm0
incq %rbx
cmpq %rbx, %r13
jne 0x38f5
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax,%r14,8)
incq %r14
movq 0x80(%rsp), %r12
cmpq %r12, %r14
jne 0x38e1
xorl %esi, %esi
movq %r12, %rax
movq %rbp, %rcx
movq 0x40(%rsp), %r11
movq %r11, %rdx
movq 0x60(%rsp), %r13
movl 0xe0(%rsp), %r14d
movq %rsi, %rdi
incq %rsi
cmpq %r12, %rsi
jae 0x3a5c
movl $0x1, %r8d
movsd (%r11,%rdi,8), %xmm0
movsd (%rdx,%r8,8), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3a54
movl (%rbp,%rdi,4), %r9d
movsd %xmm1, (%r11,%rdi,8)
movsd %xmm0, (%rdx,%r8,8)
movl (%rcx,%r8,4), %r10d
movl %r10d, (%rbp,%rdi,4)
movl %r9d, (%rcx,%r8,4)
incq %r8
cmpl %r8d, %eax
jne 0x3a24
addq $0x8, %rdx
addq $0x4, %rcx
decq %rax
cmpq %r12, %rsi
jne 0x3a13
cmpl $0x0, 0x38(%rsp)
sete %al
testl %r14d, %r14d
sete %cl
orb %al, %cl
movl 0xd0(%rsp), %eax
jne 0x40c1
testl %eax, %eax
setne 0x28(%rsp)
decl %r14d
movq 0x38(%rsp), %rax
decl %eax
cmpl %eax, %r14d
cmovbl %r14d, %eax
incl %eax
movq %rax, 0x38(%rsp)
xorl %r14d, %r14d
movl (%rbp,%r14,4), %eax
movl $0x1, %ebx
testl %eax, %eax
je 0x3ade
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
callq 0x2070
callq 0x2230
addsd 0x1727(%rip), %xmm0     # 0x5200
cvttsd2si %xmm0, %rbx
movl $0x1, %r15d
movl $0x1, %r12d
testq %r14, %r14
je 0x3b16
movl %r14d, %eax
negl %eax
cmovsl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
callq 0x2070
callq 0x2230
addsd 0x16ef(%rip), %xmm0     # 0x5200
cvttsd2si %xmm0, %r12
movq 0x40(%rsp), %rax
movsd (%rax,%r14,8), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x2270
cvttsd2si 0x90(%rsp), %eax
testl %eax, %eax
je 0x3b66
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
callq 0x2070
callq 0x2230
addsd 0x169f(%rip), %xmm0     # 0x5200
cvttsd2si %xmm0, %r15
addl %ebx, %r12d
xorl %eax, %eax
xorpd %xmm0, %xmm0
ucomisd 0x10(%rsp), %xmm0
seta %al
addl %r12d, %eax
leal (%r15,%rax), %r12d
addl $0xe, %r12d
movl (%rbp,%r14,4), %eax
movq 0x78(%rsp), %rcx
movq (%rcx,%rax,8), %rbx
movq %rbx, %rdi
callq 0x2050
leaq 0x1(%rax), %rdi
callq 0x2170
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x20c0
movq %r15, 0x70(%rsp)
movq %r15, %rdi
leaq 0x1679(%rip), %rsi      # 0x5238
leaq 0x58(%rsp), %rdx
callq 0x2280
movq %rax, %rbx
movl $0x0, 0xc(%rsp)
movl %r12d, 0x8(%rsp)
movq 0x43f0(%rip), %rdi      # 0x7fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x5, 0x8(%rdi,%rax)
leaq 0x1(%r14), %rsi
movq %rsi, 0x68(%rsp)
callq 0x2090
movq %rax, %r15
movl $0x3, %edx
movq %rax, %rdi
leaq 0x184f(%rip), %rsi      # 0x545f
callq 0x2120
movl (%rbp,%r14,4), %esi
movq %r15, %rdi
callq 0x2090
movq %rax, %r15
movl $0x3, %edx
movq %rax, %rdi
leaq 0x182f(%rip), %rsi      # 0x5463
callq 0x2120
movq (%r15), %rax
movq -0x18(%rax), %rax
movl 0x18(%r15,%rax), %ecx
movl $0xfffffefb, %edx       # imm = 0xFFFFFEFB
andl %edx, %ecx
orl $0x4, %ecx
movl %ecx, 0x18(%r15,%rax)
movq %r15, %rdi
movsd 0x10(%rsp), %xmm0
callq 0x2210
movl $0x2, %edx
movq %rax, %rdi
leaq 0x17f6(%rip), %rsi      # 0x5467
callq 0x2120
testq %rbx, %rbx
je 0x4014
movl 0xe8(%rsp), %eax
movl %r12d, 0x20(%rsp)
subl %r12d, %eax
movq %rax, 0x48(%rsp)
xorl %r14d, %r14d
movq $0x0, 0x10(%rsp)
movl 0xd0(%rsp), %r15d
movq %rbx, %rdi
callq 0x2050
cmpq 0x48(%rsp), %rax
jbe 0x3ccb
movl 0x8(%rsp), %ecx
movl %ecx, 0x50(%rsp)
cmpl 0xe8(%rsp), %ecx
jne 0x3d92
movl 0x8(%rsp), %r12d
movl 0xe8(%rsp), %ecx
subl %r12d, %ecx
cmpq %rcx, %rax
jbe 0x3d0d
cmpl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rdx
jle 0x3f87
xorl %r14d, %r14d
movl 0x20(%rsp), %edi
leaq 0x8(%rsp), %rsi
leaq 0xc(%rsp), %rcx
xorl %r8d, %r8d
callq 0x32a0
jmp 0x3fea
movb 0x28(%rsp), %bpl
testl %r15d, %r15d
je 0x3d52
movq 0x8(%r13), %rdi
movq %rbx, %rsi
callq 0x2190
movb 0x28(%rsp), %bpl
testl %eax, %eax
je 0x3d52
movl $0x2, %r14d
cmpl %r15d, %r14d
setbe %bpl
ja 0x3d52
movl %r14d, %eax
movq (%r13,%rax,8), %rdi
movq %rbx, %rsi
callq 0x2190
incl %r14d
testl %eax, %eax
jne 0x3d32
testb %bpl, %bpl
je 0x3f24
movl 0xc(%rsp), %r14d
addl $0x2, %r14d
movl %r14d, 0xc(%rsp)
movq %rbx, %rdi
callq 0x2050
leal (%rax,%r12), %ecx
movq 0x10(%rsp), %rdi
movl %r14d, %esi
movl %r12d, %edx
callq 0x3789
movq %rax, %r14
movq 0x30(%rsp), %rbp
jmp 0x3f2e
movb 0x28(%rsp), %bpl
testl %r15d, %r15d
je 0x3ddc
movq 0x8(%r13), %rdi
movq %rbx, %rsi
callq 0x2190
movb 0x28(%rsp), %bpl
testl %eax, %eax
je 0x3ddc
movl $0x2, %r15d
cmpl 0xd0(%rsp), %r15d
setbe %bpl
ja 0x3ddc
movl %r15d, %eax
movq (%r13,%rax,8), %rdi
movq %rbx, %rsi
callq 0x2190
incl %r15d
testl %eax, %eax
jne 0x3db7
cmpb $0x0, (%rbx)
je 0x3ede
movl $0x1, %r12d
xorl %r13d, %r13d
xorl %r15d, %r15d
movl 0x8(%rsp), %eax
incl %eax
cmpl 0xe8(%rsp), %eax
jbe 0x3e93
testb %bpl, %bpl
movq 0x10(%rsp), %rdx
je 0x3e39
testb $0x1, %r15b
jne 0x3e4f
movl 0xc(%rsp), %esi
addl $0x2, %esi
movl %esi, 0xc(%rsp)
movq %rdx, %rdi
movl 0x50(%rsp), %edx
movl 0xe8(%rsp), %ecx
callq 0x3789
movl 0x20(%rsp), %r15d
jmp 0x3e73
cmpl $0x0, 0xc(%rsp)
jle 0x3ece
movl 0x20(%rsp), %edi
leaq 0x8(%rsp), %rsi
jmp 0x3e83
movl $0x2, 0xc(%rsp)
movq %rdx, %rdi
movl $0x2, %esi
movl 0x20(%rsp), %r15d
movl %r15d, %edx
movl 0xe8(%rsp), %ecx
callq 0x3789
movl %r15d, %edi
leaq 0x8(%rsp), %rsi
movq %rax, 0x10(%rsp)
movq %rax, %rdx
leaq 0xc(%rsp), %rcx
xorl %r8d, %r8d
callq 0x32a0
movb $0x1, %r15b
incl 0x8(%rsp)
movb (%rbx,%r13), %al
movb %al, 0x1f(%rsp)
movl $0x1, %edx
movq 0x4125(%rip), %rdi      # 0x7fd0
leaq 0x1f(%rsp), %rsi
callq 0x2120
movl %r12d, %r13d
movq %rbx, %rdi
callq 0x2050
incl %r12d
cmpq %r13, %rax
ja 0x3df1
jmp 0x3ede
movl 0x20(%rsp), %edi
leaq 0x8(%rsp), %rsi
callq 0x341d
jmp 0x3e90
testb %bpl, %bpl
je 0x3f9a
movl $0x2, 0xc(%rsp)
movl 0x8(%rsp), %ecx
movq 0x10(%rsp), %rdi
movl $0x2, %esi
movl 0x20(%rsp), %r12d
movl %r12d, %edx
callq 0x3789
movq %rax, %r8
movq 0x30(%rsp), %rbp
movq 0x60(%rsp), %r13
movl 0xd0(%rsp), %r15d
jmp 0x3fb6
movq 0x30(%rsp), %rbp
movq 0x10(%rsp), %r14
movq %rbx, %rdi
callq 0x2050
movq 0x4093(%rip), %rdi      # 0x7fd0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x2120
movq %rbx, %rdi
callq 0x2050
addl %eax, 0x8(%rsp)
movq 0x58(%rsp), %rdi
movl 0xe8(%rsp), %esi
movl 0x20(%rsp), %edx
leaq 0x8(%rsp), %rcx
movq %r14, 0x10(%rsp)
movq %r14, %r8
leaq 0xc(%rsp), %r9
callq 0x3484
movb $0x1, %r14b
testb %al, %al
je 0x3fea
jmp 0x401d
movl 0x20(%rsp), %edi
leaq 0x8(%rsp), %rsi
callq 0x341d
xorl %r14d, %r14d
jmp 0x3fea
movq 0x30(%rsp), %rbp
movq 0x60(%rsp), %r13
movl 0xd0(%rsp), %r15d
movl 0x20(%rsp), %r12d
movq 0x10(%rsp), %r8
movq 0x58(%rsp), %rdi
movl 0xe8(%rsp), %esi
movl %r12d, %edx
leaq 0x8(%rsp), %rcx
movq %r8, 0x10(%rsp)
leaq 0xc(%rsp), %r9
callq 0x3484
movzbl %r14b, %r14d
testb %al, %al
movl $0x1, %eax
cmovel %eax, %r14d
jne 0x401d
testb $0x1, %r14b
je 0x4009
movq 0x58(%rsp), %rdi
leaq 0x123c(%rip), %rsi      # 0x5238
leaq 0x58(%rsp), %rdx
callq 0x2280
movq %rax, %rbx
testq %rbx, %rbx
jne 0x3ca7
jmp 0x401d
movq $0x0, 0x10(%rsp)
movq 0x3fac(%rip), %r14      # 0x7fd0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x20d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20a0
movl 0xe8(%rsp), %eax
movl %eax, %ebx
testl %eax, %eax
leaq 0x140d(%rip), %r15      # 0x546a
je 0x4073
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x2120
decl %ebx
jne 0x405f
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x20d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20a0
movq 0x10(%rsp), %rdi
callq 0x2140
movq 0x70(%rsp), %rdi
callq 0x2140
movq 0x68(%rsp), %rax
movq %rax, %r14
cmpq 0x38(%rsp), %rax
jne 0x3aab
movq 0x40(%rsp), %rdi
callq 0x2140
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)