// File: /workspace/github_cpp_makefile_star2_O1/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 $0x88, %rsp
movq %rsi, %rbx
movq %rdi, 0x28(%rsp)
callq 0x300fc
leaq 0x68(%rsp), %rdi
callq 0x3372c
leaq 0x48(%rsp), %rdi
callq 0x3372c
movq %rbx, 0x30(%rsp)
testq %rbx, %rbx
jle 0xa104f
xorl %edx, %edx
leaq (%rdx,%rdx,2), %rax
movq 0x28(%rsp), %rcx
leaq (%rcx,%rax,8), %rbx
cmpl $0x0, 0xc(%rbx)
movl $0x0, %r13d
je 0xa103d
movq %rdx, 0x38(%rsp)
xorl %r13d, %r13d
xorl %r15d, %r15d
movq %rbx, 0x20(%rsp)
movq (%rbx), %rcx
leaq (%r15,%r15,4), %r12
movq (%rcx,%r12,8), %rax
movl 0xc(%rcx,%r12,8), %esi
leaq (%rsi,%rsi,2), %rdx
movq 0x28(%rsp), %rdi
leaq (%rdi,%rdx,8), %r14
movl 0xc(%r14), %edi
movq $-0x1, %rdx
testq %rdi, %rdi
je 0xa0e7a
movq %rax, %r8
shrq $0x20, %r8
movq (%r14), %r9
xorl %r10d, %r10d
cmpl %r8d, 0xc(%r9)
jne 0xa0e69
cmpl 0x4(%r9), %esi
je 0xa0e77
incq %r10
addq $0x28, %r9
cmpq %r10, %rdi
jne 0xa0e5d
jmp 0xa0e7a
movq %r10, %rdx
cmpq $-0x1, %rdx
je 0xa1000
leaq (%rcx,%r12,8), %rsi
movq (%r14), %rcx
leaq (%rdx,%rdx,4), %rbp
cmpl %eax, 0x10(%rcx,%rbp,8)
jne 0xa0ec2
leaq (%rcx,%rbp,8), %rdi
movl 0x8(%rsi), %eax
cmpl 0x14(%rdi), %eax
jne 0xa0ec2
movl 0x10(%rsi), %eax
cmpl (%rdi), %eax
jne 0xa0ec2
movl 0x14(%rsi), %eax
cmpl 0x8(%rdi), %eax
jne 0xa0ec2
movl 0x18(%rdi), %eax
xorl 0x18(%rsi), %eax
js 0xa0ec2
callq 0xa052a
jmp 0xa0fd1
movq %r13, 0x8(%rsp)
movq %rsi, %rdi
leaq 0x68(%rsp), %r13
movq %r13, %rsi
leaq 0x48(%rsp), %rbx
movq %rbx, %rdx
leaq 0x1c(%rsp), %rcx
leaq 0x18(%rsp), %r8
callq 0xa0c87
movq %rbp, 0x40(%rsp)
leaq (,%rbp,8), %rbp
movq (%r14), %rdi
addq %rbp, %rdi
movq %r13, %rsi
movq %rbx, %rdx
leaq 0x14(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0xa0c87
movl 0x1c(%rsp), %ecx
testl %ecx, %ecx
setne %dl
movl 0x18(%rsp), %eax
testl %eax, %eax
setne %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0xa0f3b
cmpl $0x0, 0x14(%rsp)
je 0xa0fb1
cmpl $0x0, 0x10(%rsp)
je 0xa0fb1
movl 0x14(%rsp), %esi
testl %esi, %esi
setne %dil
movl 0x10(%rsp), %edx
testl %edx, %edx
setne %r8b
andb %dil, %r8b
cmpb $0x1, %r8b
movq 0x20(%rsp), %rbx
jne 0xa0f82
testl %ecx, %ecx
sete %dil
testl %eax, %eax
sete %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
jne 0xa0f82
leaq (,%r12,8), %rdi
addq (%rbx), %rdi
addq (%r14), %rbp
jmp 0xa0fac
addl %ecx, %eax
addl %esi, %edx
cmpl %edx, %eax
jbe 0xa0f97
addq (%r14), %rbp
leaq (,%r12,8), %rsi
jmp 0xa0fc1
leaq (,%r12,8), %rsi
addq (%rbx), %rsi
cmpl %edx, %eax
jae 0xa1011
addq (%r14), %rbp
movq %rsi, %rdi
movq %rbp, %rsi
jmp 0xa0fc7
addq (%r14), %rbp
leaq (,%r12,8), %rsi
movq 0x20(%rsp), %rbx
addq (%rbx), %rsi
movq %rbp, %rdi
callq 0xa052a
movq 0x8(%rsp), %r13
movq (%rbx), %rax
leaq (,%r13,4), %rcx
addq %r13, %rcx
movq 0x20(%rax,%r12,8), %rdx
movq %rdx, 0x20(%rax,%rcx,8)
movups (%rax,%r12,8), %xmm0
movups 0x10(%rax,%r12,8), %xmm1
movups %xmm1, 0x10(%rax,%rcx,8)
movups %xmm0, (%rax,%rcx,8)
incq %r13
incq %r15
movl 0xc(%rbx), %eax
cmpq %rax, %r15
jb 0xa0e23
jmp 0xa1038
movl 0x8(%rsi), %ecx
subl (%rsi), %ecx
movq (%r14), %rax
movq 0x40(%rsp), %rdx
leaq (%rax,%rdx,8), %rax
movl 0x8(%rax), %edx
subl (%rax), %edx
cmpl %edx, %ecx
jae 0xa1033
movq %rsi, %rdi
movq %rax, %rsi
jmp 0xa0fc7
movq %rax, %rdi
jmp 0xa0fc7
movq 0x38(%rsp), %rdx
movl %r13d, 0xc(%rbx)
incq %rdx
cmpq 0x30(%rsp), %rdx
jne 0xa0df6
leaq 0x68(%rsp), %rdi
callq 0x33667
leaq 0x48(%rsp), %rdi
callq 0x33667
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq