// File: /workspace/github_cpp_makefile_star2_O2/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, 0x18(%rsp)
callq 0x251c
leaq 0x58(%rsp), %rdi
callq 0x6bd1
leaq 0x38(%rsp), %rdi
callq 0x6bd1
xorl %eax, %eax
testq %rbx, %rbx
cmovleq %rax, %rbx
movq %rbx, 0x20(%rsp)
cmpq 0x20(%rsp), %rax
je 0x69fbf
movq %rax, 0x28(%rsp)
imulq $0x18, %rax, %r13
addq 0x18(%rsp), %r13
xorl %r12d, %r12d
xorl %ecx, %ecx
xorl %ebp, %ebp
movl 0xc(%r13), %eax
cmpq %rax, %rcx
jae 0x69fae
movq %rcx, 0x30(%rsp)
movq (%r13), %r15
movq (%r15,%r12), %r14
movq %r14, %rdx
shrq $0x20, %rdx
movl 0xc(%r15,%r12), %esi
imulq $0x18, %rsi, %rbx
addq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x696ab
cmpq $-0x1, %rax
je 0x69f75
movq %rbp, (%rsp)
leaq (%r15,%r12), %rsi
movq (%rbx), %rdi
imulq $0x28, %rax, %rbp
cmpl %r14d, 0x10(%rdi,%rbp)
jne 0x69e6b
addq %rbp, %rdi
movl 0x8(%r15,%r12), %eax
cmpl 0x14(%rdi), %eax
jne 0x69e6b
movl 0x10(%r15,%r12), %eax
cmpl (%rdi), %eax
jne 0x69e6b
movl 0x14(%r15,%r12), %eax
cmpl 0x8(%rdi), %eax
jne 0x69e6b
movl 0x18(%rdi), %eax
xorl 0x18(%r15,%r12), %eax
jns 0x69f43
movq %rsi, %rdi
leaq 0x58(%rsp), %r14
movq %r14, %rsi
leaq 0x38(%rsp), %r15
movq %r15, %rdx
leaq 0x14(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0x69c75
movq (%rbx), %rdi
addq %rbp, %rdi
movq %r14, %rsi
movq %r15, %rdx
leaq 0xc(%rsp), %rcx
leaq 0x8(%rsp), %r8
callq 0x69c75
movl 0x14(%rsp), %ecx
testl %ecx, %ecx
setne %dl
movl 0x10(%rsp), %eax
testl %eax, %eax
setne %dil
andb %dl, %dil
movl 0xc(%rsp), %esi
movl 0x8(%rsp), %edx
cmpb $0x1, %dil
jne 0x69ee1
testl %esi, %esi
sete %dil
testl %edx, %edx
sete %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
je 0x69f1f
testl %esi, %esi
setne %dil
testl %edx, %edx
setne %r8b
andb %dil, %r8b
cmpb $0x1, %r8b
jne 0x69f17
testl %ecx, %ecx
sete %dil
testl %eax, %eax
sete %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
jne 0x69f17
movq (%r13), %rdi
addq %r12, %rdi
addq (%rbx), %rbp
jmp 0x69f40
addl %ecx, %eax
addl %esi, %edx
cmpl %edx, %eax
jbe 0x69f2e
addq (%rbx), %rbp
movq (%r13), %rsi
addq %r12, %rsi
movq %rbp, %rdi
jmp 0x69f43
movq (%r13), %rcx
leaq (%rcx,%r12), %rsi
cmpl %edx, %eax
jae 0x69f86
addq (%rbx), %rbp
movq %rsi, %rdi
movq %rbp, %rsi
callq 0x696da
movq (%rsp), %rbp
movq (%r13), %rax
imulq $0x28, %rbp, %rcx
movq 0x20(%rax,%r12), %rdx
movq %rdx, 0x20(%rax,%rcx)
movups (%rax,%r12), %xmm0
movups 0x10(%rax,%r12), %xmm1
movups %xmm1, 0x10(%rax,%rcx)
movups %xmm0, (%rax,%rcx)
incq %rbp
movq 0x30(%rsp), %rcx
incq %rcx
addq $0x28, %r12
jmp 0x69de6
movl 0x8(%rcx,%r12), %edx
subl (%rcx,%r12), %edx
movq (%rbx), %rcx
leaq (%rcx,%rbp), %rax
movl 0x8(%rcx,%rbp), %edi
subl (%rcx,%rbp), %edi
cmpl %edi, %edx
jae 0x69fa9
movq %rsi, %rdi
movq %rax, %rsi
jmp 0x69f43
movq %rax, %rdi
jmp 0x69f43
movl %ebp, 0xc(%r13)
movq 0x28(%rsp), %rax
incq %rax
jmp 0x69dc6
leaq 0x58(%rsp), %rdi
callq 0x6b07
leaq 0x38(%rsp), %rdi
callq 0x6b07
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq