// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Overlaps.cpp
// Function: normalize_ma_hit_t_single_side_aggressive(ma_hit_t_alloc*, long long)
void normalize_ma_hit_t_single_side_aggressive(ma_hit_t_alloc* sources, long long num_sources)
{
    double startTime = Get_T();

    ///long long debug_prefect = 0, debug_not_bad = 0, debug_bad = 0;

    UC_Read query, target;
    init_UC_Read(&query);
    init_UC_Read(&target);

    long long i, j, index;
    uint32_t qn, tn, queryLeftLen, queryRightLen, targetLeftLen, targetRightLen;
    long long qLen_0, qLen_1, m;
    for (i = 0; i < num_sources; i++)
    {

        m = 0;
        for (j = 0; j < sources[i].length; j++)
        {
            qn = Get_qn(sources[i].buffer[j]);
            tn = Get_tn(sources[i].buffer[j]);

            // sources[i].buffer[j].bl = Get_qe(sources[i].buffer[j]) - Get_qs(sources[i].buffer[j]);

            index = get_specific_overlap(&(sources[tn]), tn, qn);


            if(index != -1)
            {
                // sources[tn].buffer[index].bl = Get_qe(sources[tn].buffer[index]) 
                //                                             - Get_qs(sources[tn].buffer[index]);

                if(Get_qs(sources[i].buffer[j]) == Get_ts(sources[tn].buffer[index])
                    &&
                   Get_qe(sources[i].buffer[j]) == Get_te(sources[tn].buffer[index])
                    && 
                   Get_ts(sources[i].buffer[j]) == Get_qs(sources[tn].buffer[index])
                    &&
                   Get_te(sources[i].buffer[j]) == Get_qe(sources[tn].buffer[index])
                    &&
                   sources[i].buffer[j].rev == sources[tn].buffer[index].rev)
                {
                    ///actually two edges are same, here is just to unify el, ml, no_l_indel, bl
                    set_reverse_overlap(&(sources[tn].buffer[index]), &(sources[i].buffer[j]));

                    sources[i].buffer[m] = sources[i].buffer[j];
                    m++;

                    ///debug_prefect++;
                    continue;
                }


                get_end_match_length(&(sources[i].buffer[j]), &query, &target,
                &queryLeftLen, &queryRightLen);

                get_end_match_length(&(sources[tn].buffer[index]), &query, &target,
                &targetLeftLen, &targetRightLen);

                ///query is right
                if(queryLeftLen>0 && queryRightLen>0 && (targetLeftLen==0 || targetRightLen==0))
                {
                    set_reverse_overlap(&(sources[tn].buffer[index]), &(sources[i].buffer[j]));

                    sources[i].buffer[m] = sources[i].buffer[j];
                    m++;

                    ///debug_not_bad++;
                    continue;
                }


                ///target is right
                if(targetLeftLen>0 && targetRightLen>0 && (queryLeftLen==0 || queryRightLen==0))
                {
                    set_reverse_overlap(&(sources[i].buffer[j]), &(sources[tn].buffer[index]));

                    sources[i].buffer[m] = sources[i].buffer[j];
                    m++;

                    ///debug_not_bad++;
                    continue;
                }


                ///query is right
                if((queryLeftLen+queryRightLen)>(targetLeftLen+targetRightLen))
                {
                    set_reverse_overlap(&(sources[tn].buffer[index]), &(sources[i].buffer[j]));
                }///target is right
                else if((queryLeftLen+queryRightLen)<(targetLeftLen+targetRightLen))
                {
                    set_reverse_overlap(&(sources[i].buffer[j]), &(sources[tn].buffer[index]));
                }
                else
                {
                    qLen_0 = Get_qe(sources[i].buffer[j]) - Get_qs(sources[i].buffer[j]);
                    qLen_1 = Get_qe(sources[tn].buffer[index]) - Get_qs(sources[tn].buffer[index]);
                    if(qLen_0 >= qLen_1)
                    {
                        set_reverse_overlap(&(sources[tn].buffer[index]), &(sources[i].buffer[j]));
                    }
                    else
                    {
                        set_reverse_overlap(&(sources[i].buffer[j]), &(sources[tn].buffer[index]));
                    }
                }

                sources[i].buffer[m] = sources[i].buffer[j];
                m++;

                ///debug_bad++;
            }
        }

        sources[i].length = m;
    }

    destory_UC_Read(&query);
    destory_UC_Read(&target);

    if(VERBOSE >= 1)
    {
        fprintf(stderr, "[M::%s] takes %0.2fs\n\n", __func__, Get_T()-startTime);
    }

    // fprintf(stderr, "debug_prefect: %ld, debug_not_bad: %ld, debug_bad: %ld\n", debug_prefect, debug_not_bad,
    // debug_bad);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %rbx
movq %rdi, %r14
callq 0x2f3fc
leaq 0x58(%rsp), %rdi
callq 0x32e2d
leaq 0x38(%rsp), %rdi
callq 0x32e2d
movq %rbx, 0x20(%rsp)
testq %rbx, %rbx
jle 0xa1767
xorl %ecx, %ecx
movq %r14, 0x18(%rsp)
leaq (%rcx,%rcx,2), %rax
leaq (%r14,%rax,8), %r13
cmpl $0x0, 0xc(%r13)
movl $0x0, %r11d
je 0xa1755
movq %rcx, 0x28(%rsp)
xorl %r11d, %r11d
xorl %r12d, %r12d
movq (%r13), %rcx
leaq (%r12,%r12,4), %rbx
movl 0xc(%rcx,%rbx,8), %eax
leaq (%rax,%rax,2), %rdi
movl 0xc(%r14,%rdi,8), %r8d
testq %r8, %r8
je 0xa171a
leaq (%rcx,%rbx,8), %rsi
movq (%rsi), %rcx
movq %rcx, %rdx
shrq $0x20, %rdx
leaq (%r14,%rdi,8), %r15
movq (%r15), %rdi
shlq $0x3, %r8
leaq (%r8,%r8,4), %r8
xorl %ebp, %ebp
cmpl %edx, 0xc(%rdi,%rbp)
jne 0xa159f
movq (%rdi,%rbp), %r9
movq %r9, %r10
shrq $0x20, %r10
cmpl %r10d, %eax
je 0xa15ad
addq $0x28, %rbp
cmpq %rbp, %r8
jne 0xa1589
jmp 0xa171a
movq %r11, 0x30(%rsp)
cmpl %ecx, 0x10(%rdi,%rbp)
jne 0xa15e1
movl 0x8(%rsi), %eax
cmpl 0x14(%rdi,%rbp), %eax
jne 0xa15e1
cmpl %r9d, 0x10(%rsi)
jne 0xa15e1
movl 0x14(%rsi), %eax
cmpl 0x8(%rdi,%rbp), %eax
jne 0xa15e1
movl 0x18(%rdi,%rbp), %eax
xorl 0x18(%rsi), %eax
js 0xa15e1
addq %rbp, %rdi
jmp 0xa16e9
movq %rsi, %rdi
leaq 0x58(%rsp), %r14
movq %r14, %rsi
leaq 0x38(%rsp), %rdx
leaq 0x14(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0xa13b6
movq (%r15), %rdi
addq %rbp, %rdi
movq %r14, %rsi
leaq 0x38(%rsp), %rdx
leaq 0xc(%rsp), %rcx
leaq 0x8(%rsp), %r8
callq 0xa13b6
movl 0x14(%rsp), %edx
testl %edx, %edx
setne %cl
movl 0x10(%rsp), %eax
testl %eax, %eax
setne %dil
andb %cl, %dil
movl 0xc(%rsp), %esi
movl 0x8(%rsp), %ecx
cmpb $0x1, %dil
jne 0xa1674
testl %esi, %esi
sete %dil
testl %ecx, %ecx
sete %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
jne 0xa1674
addq (%r15), %rbp
leaq (,%rbx,8), %rsi
addq (%r13), %rsi
movq %rbp, %rdi
callq 0xa0cca
movq 0x18(%rsp), %r14
jmp 0xa16ee
testl %esi, %esi
setne %dil
testl %ecx, %ecx
setne %r8b
andb %dil, %r8b
cmpb $0x1, %r8b
movq 0x18(%rsp), %r14
jne 0xa16b4
testl %edx, %edx
sete %dil
testl %eax, %eax
sete %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
jne 0xa16b4
leaq (,%rbx,8), %rdi
addq (%r13), %rdi
addq (%r15), %rbp
jmp 0xa16e6
addl %edx, %eax
addl %esi, %ecx
cmpl %ecx, %eax
jbe 0xa16d0
addq (%r15), %rbp
leaq (,%rbx,8), %rsi
addq (%r13), %rsi
movq %rbp, %rdi
jmp 0xa16e9
leaq (,%rbx,8), %rsi
addq (%r13), %rsi
cmpl %ecx, %eax
jae 0xa172c
addq (%r15), %rbp
movq %rsi, %rdi
movq %rbp, %rsi
callq 0xa0cca
movq (%r13), %rax
movq 0x30(%rsp), %r11
leaq (%r11,%r11,4), %rcx
movq 0x20(%rax,%rbx,8), %rdx
movq %rdx, 0x20(%rax,%rcx,8)
movups (%rax,%rbx,8), %xmm0
movups 0x10(%rax,%rbx,8), %xmm1
movups %xmm1, 0x10(%rax,%rcx,8)
movups %xmm0, (%rax,%rcx,8)
incq %r11
incq %r12
movl 0xc(%r13), %eax
cmpq %rax, %r12
jb 0xa154c
jmp 0xa1750
movl 0x8(%rsi), %ecx
subl (%rsi), %ecx
movq (%r15), %rdx
leaq (%rdx,%rbp), %rax
movl 0x8(%rdx,%rbp), %edi
subl (%rdx,%rbp), %edi
cmpl %edi, %ecx
jae 0xa174b
movq %rsi, %rdi
movq %rax, %rsi
jmp 0xa16e9
movq %rax, %rdi
jmp 0xa16e9
movq 0x28(%rsp), %rcx
movl %r11d, 0xc(%r13)
incq %rcx
cmpq 0x20(%rsp), %rcx
jne 0xa1528
leaq 0x58(%rsp), %rdi
callq 0x32d68
leaq 0x38(%rsp), %rdi
callq 0x32d68
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq