// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Overlaps.cpp
// Function: cut_trio_tip_primary(asg_t*, ma_ug_t*, unsigned int, unsigned int, unsigned int, asg_t*, ma_hit_t_alloc*, R_to_U*, unsigned char*, unsigned int)
int cut_trio_tip_primary(asg_t *g, ma_ug_t *ug, uint32_t max_ext, uint32_t trio_flag, uint32_t keep_out_node,
asg_t *read_sg, ma_hit_t_alloc* reverse_sources, R_to_U* ruIndex, uint8_t* is_r_het, uint32_t min_edge_length)
{
    double startTime = Get_T();
    uint32_t n_vtx = g->n_seq * 2, v, w, i, cnt = 0, tipEvaluateLen, flag, inner_flag, operation, tip_trio_flag;
    uint32_t non_trio_flag = (uint32_t)-1, nw;
    asg_arc_t *aw = NULL;
    if(trio_flag == FATHER) non_trio_flag = MOTHER;
    if(trio_flag == MOTHER) non_trio_flag = FATHER;

    buf_t b, b_0, b_1;
    
    memset(&b, 0, sizeof(buf_t));
    memset(&b_0, 0, sizeof(buf_t));
    memset(&b_1, 0, sizeof(buf_t));

    for (v = 0; v < n_vtx; ++v) 
    {
        if (g->seq[v>>1].del || g->seq[v>>1].c == ALTER_LABLE) continue;
        if (g->seq[v>>1].c == CUT || g->seq[v>>1].c == CUT_DIF_HAP || g->seq[v>>1].c == TRIM) continue;
        if(get_real_length(g, (v^1), NULL) != 0) continue;
        ///cut tip of length <= max_ext
        flag = check_tip(g, v, &w, &b, max_ext);
        if(flag == LOOP || flag == LONG_TIPS) continue;
        if(keep_out_node && flag == MUL_OUTPUT) continue;
        if(ug!=NULL)
        {
            tipEvaluateLen = 0;
            for (i = 0; i < b.b.n; ++i)
            {
                tipEvaluateLen += EvaluateLen(ug->u, (b.b.a[i]>>1));
            }
            if(tipEvaluateLen > max_ext) continue;
        }

        operation = TRIM;
        ///we need to deal with MUL_INPUT and END_TIPS
        ///two operations: 1. trimming 2. cutting
        if(flag == END_TIPS)
        {
            tip_trio_flag = cal_trio_vec(&b, ug, TRIO_THRES);
            if(((tip_trio_flag == FATHER) || (tip_trio_flag == MOTHER))
                &&
                (tip_trio_flag != non_trio_flag))
            {
                operation = CUT;
            }
        }

        ///if(flag == MUL_INPUT || flag == MUL_OUTPUT)
        if(flag == MUL_INPUT)
        {
            // tip_trio_flag = cal_trio_vec(&b, ug, TRIO_THRES);
            // if(((tip_trio_flag == FATHER) || (tip_trio_flag == MOTHER))
            //     &&
            //     (tip_trio_flag != non_trio_flag))
            // {
            //     operation = CUT;
            // }
            /**
            To do lists: we can refine this function at the final step
            1. ideally, we should check if this tip comes from different haplotype with another unitig.
            That might be helpful to recover bubbles. We should keep all break points in a vector, 
            and break these types of tip. At last, recover them.
            
            2. if this tip has enough haplotype information, we should check if it does not
            come from different haplotype with another unitig. If it does not, do not trim them
            if(operation == TRIM)
            {
                get_real_length(g, b.b.a[b.b.n-1], &w);
                w = w^1;
                ;
            }
            **/
            get_real_length(g, b.b.a[b.b.n-1], &w);
            w = w^1;
            aw = asg_arc_a(g, w);
            nw = asg_arc_n(g, w);
            for (i = 0; i < nw; ++i)
            {
                if(operation == CUT) break;
                if(aw[i].del) continue;
                if(aw[i].v == (b.b.a[b.b.n-1]^1)) continue;
                inner_flag = check_different_haps(g, ug, read_sg, b.b.a[b.b.n-1]^1, aw[i].v,
                reverse_sources, &b_0, &b_1, ruIndex, is_r_het, min_edge_length, 1);
                if(inner_flag == NON_PLOID) operation = CUT;
            }
        }

        
        for (i = 0; i < b.b.n; ++i)
        {
            g->seq[(b.b.a[i]>>1)].c = ALTER_LABLE;
        }

        for (i = 0; i < b.b.n; ++i)
        {
            asg_seq_drop(g, (b.b.a[i]>>1));
        }
        

        if(operation == CUT)
        {
            for (i = 0; i < b.b.n; ++i)
            {
                g->seq[(b.b.a[i]>>1)].c = CUT;
            }
        }
        
		++cnt;
    }


    if (cnt > 0) asg_cleanup(g);
    if(VERBOSE >= 1)
    {
        fprintf(stderr, "[M::%s] cut %d tips\n", __func__, cnt);
        fprintf(stderr, "[M::%s] takes %0.2f s\n\n", __func__, Get_T()-startTime);
    }
    free(b.b.a);
    free(b_0.b.a);
    free(b_1.b.a);


	return cnt;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movq %r9, 0x38(%rsp)
movl %r8d, 0x30(%rsp)
movl %ecx, %r14d
movl %edx, 0x14(%rsp)
movq %rsi, %r12
movq %rdi, %rbx
callq 0x2f3fc
movl 0x14(%rbx), %ebp
addl %ebp, %ebp
xorl %eax, %eax
cmpl $0x1, %r14d
sete %al
leal (%rax,%rax,2), %eax
decl %eax
cmpl $0x2, %r14d
movl $0x1, %r13d
cmovnel %eax, %r13d
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x90(%rsp)
xorl %r14d, %r14d
movq %r14, 0xa0(%rsp)
movaps %xmm0, 0x120(%rsp)
movaps %xmm0, 0x130(%rsp)
movaps %xmm0, 0x140(%rsp)
movaps %xmm0, 0x150(%rsp)
movaps %xmm0, 0x160(%rsp)
movaps %xmm0, 0x170(%rsp)
movq %r14, 0x180(%rsp)
movaps %xmm0, 0xb0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movaps %xmm0, 0xf0(%rsp)
movaps %xmm0, 0x100(%rsp)
movq %r14, 0x110(%rsp)
testl %ebp, %ebp
je 0xce3ce
xorl %r14d, %r14d
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl $0x1c02, %esi           # imm = 0x1C02
movq $0x0, 0x28(%rsp)
movq 0x20(%rbx), %rax
movl %r14d, %ecx
shrl %ecx
cmpl $0x0, (%rax,%rcx,8)
js 0xcdfb0
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xc, %eax
ja 0xcdfbd
btl %eax, %esi
jae 0xcdfbd
incl %r14d
cmpl %ebp, %r14d
jne 0xcdf92
jmp 0xce3b7
movl %r14d, %eax
xorl $0x1, %eax
movq 0x28(%rbx), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, %rcx
andq %r15, %rcx
je 0xce00e
movq 0x8(%rbx), %rdx
shrq $0x20, %rax
leaq (%rax,%rax,2), %rax
leaq (%rdx,%rax,8), %rax
addq $0xc, %rax
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rcx
xorl %edx, %edx
xorl %esi, %esi
movl (%rax,%rdx), %edi
notl %edi
shrl $0x1f, %edi
addl %edi, %esi
addq $0x18, %rdx
cmpq %rdx, %rcx
jne 0xcdff3
testl %esi, %esi
jne 0xce3ad
movq %rbx, %rdi
movl %r14d, %esi
leaq 0xc(%rsp), %rdx
leaq 0x40(%rsp), %rcx
movl 0x14(%rsp), %r8d
callq 0x105723
testl %eax, %eax
je 0xce3ad
cmpl $0x7, %eax
movl $0x1c02, %esi           # imm = 0x1C02
je 0xcdfb0
cmpl $0x0, 0x30(%rsp)
setne %cl
cmpl $0x4, %eax
sete %dl
testb %dl, %cl
jne 0xcdfb0
testq %r12, %r12
je 0xce0a0
movq 0x78(%rsp), %rcx
testq %rcx, %rcx
je 0xce0a0
movq 0x10(%r12), %rdx
xorl %esi, %esi
movq 0x88(%rsp), %rdi
xorl %r8d, %r8d
movl (%rdi,%rsi,4), %r9d
shrl %r9d
leaq (%r9,%r9,4), %r9
addl 0x4(%rdx,%r9,8), %r8d
incq %rsi
movl %esi, %r9d
cmpq %r9, %rcx
ja 0xce075
cmpl 0x14(%rsp), %r8d
movl $0x1c02, %esi           # imm = 0x1C02
ja 0xcdfb0
movl %r13d, 0x10(%rsp)
movq %r12, 0x20(%rsp)
movl $0xa, %edx
cmpl $0x3, %eax
je 0xce0ed
cmpl $0x5, %eax
jne 0xce21f
leaq 0x40(%rsp), %rdi
movq 0x20(%rsp), %rsi
movss 0x167ce5(%rip), %xmm0   # 0x235db4
callq 0xcdd7e
testl %eax, %eax
sete %cl
cmpl 0x10(%rsp), %eax
sete %al
orb %cl, %al
movzbl %al, %edx
xorl $0xb, %edx
jmp 0xce21f
movq 0x78(%rsp), %rax
movq 0x88(%rsp), %rcx
movl -0x4(%rcx,%rax,4), %esi
movq 0x8(%rbx), %rax
movq 0x28(%rbx), %rcx
movq (%rcx,%rsi,8), %rdi
movq %rdi, %rsi
andq %r15, %rsi
je 0xce147
shrq $0x20, %rdi
shlq $0x3, %rsi
leaq (%rsi,%rsi,2), %rsi
leaq (%rdi,%rdi,2), %rdi
leaq (%rax,%rdi,8), %rdi
addq $0xc, %rdi
xorl %r8d, %r8d
cmpl $0x0, (%rdi,%r8)
js 0xce13e
movl -0x4(%rdi,%r8), %r9d
movl %r9d, 0xc(%rsp)
addq $0x18, %r8
cmpq %r8, %rsi
jne 0xce12d
movl 0xc(%rsp), %esi
xorq $0x1, %rsi
movl %esi, 0xc(%rsp)
movq (%rcx,%rsi,8), %rcx
testl %ecx, %ecx
movl $0xa, %edx
je 0xce21f
movq %rcx, %rdx
shrq $0x20, %rdx
movl %ecx, %esi
leaq (%rdx,%rdx,2), %rcx
leaq (%rax,%rcx,8), %r13
addq $0xc, %r13
movl $0x1, %r12d
movq %rsi, 0x18(%rsp)
movl $0xa, %edx
cmpl $0x0, (%r13)
js 0xce205
movl -0x4(%r13), %r8d
movq 0x78(%rsp), %rax
movq 0x88(%rsp), %rcx
movl -0x4(%rcx,%rax,4), %ecx
xorl $0x1, %ecx
cmpl %ecx, %r8d
je 0xce205
movq %rbx, %rdi
movq 0x20(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq 0x1c0(%rsp), %r9
pushq $0x1
movl 0x1e0(%rsp), %eax
pushq %rax
pushq 0x1e0(%rsp)
pushq 0x1e0(%rsp)
leaq 0xd0(%rsp), %rax
pushq %rax
leaq 0x148(%rsp), %rax
pushq %rax
callq 0x105913
movq 0x48(%rsp), %rsi
addq $0x30, %rsp
xorl %edx, %edx
cmpl $0x1, %eax
sete %dl
orl $0xa, %edx
cmpl $0xb, %edx
je 0xce21f
addq $0x18, %r13
leaq 0x1(%r12), %rax
cmpq %rsi, %r12
movq %rax, %r12
jb 0xce184
movq 0x78(%rsp), %rsi
testq %rsi, %rsi
je 0xce397
movl %edx, 0x18(%rsp)
movq 0x20(%rbx), %rax
movq 0x88(%rsp), %rcx
xorl %edi, %edi
movl (%rcx,%rdi,4), %r8d
shrl %r8d
movb $0x1, 0x4(%rax,%r8,8)
incq %rdi
movl %edi, %r8d
cmpq %r8, %rsi
ja 0xce23f
xorl %eax, %eax
movl %ebp, 0x34(%rsp)
movq 0x88(%rsp), %rcx
movl (%rcx,%rax,4), %ecx
movl %ecx, %edi
shrl %edi
movq 0x20(%rbx), %r8
cmpb $0x1, 0x4(%r8,%rdi,8)
jne 0xce358
andl $-0x2, %ecx
movb $0x1, %sil
xorl %edi, %edi
orq %rcx, %rdi
movq 0x28(%rbx), %r8
movq (%r8,%rdi,8), %r9
movq %r9, %r8
andq %r15, %r8
je 0xce33b
shrq $0x20, %r9
leaq (%r9,%r9,2), %r9
shlq $0x3, %r9
addq 0x8(%rbx), %r9
xorl %r10d, %r10d
leaq (%r10,%r10,2), %r12
movl 0xc(%r9,%r12,8), %r11d
testl %r11d, %r11d
js 0xce32f
leaq (%r9,%r12,8), %r13
movq 0x20(%rbx), %rdx
movl 0x8(%r13), %ebp
movl %ebp, %r12d
shrl %r12d
cmpb $0x1, 0x4(%rdx,%r12,8)
je 0xce32f
orl $0x80000000, %r11d      # imm = 0x80000000
movl %r11d, 0xc(%r13)
xorq $0x1, %rbp
movq 0x28(%rbx), %rdx
movq (%rdx,%rbp,8), %r12
movq %r12, %r11
andq %r15, %r11
je 0xce32f
movq 0x8(%rbx), %rdx
shrq $0x20, %r12
shlq $0x3, %r11
leaq (%r11,%r11,2), %r11
leaq (%r12,%r12,2), %r12
leaq (%rdx,%r12,8), %r12
addq $0xc, %r12
xorl %r13d, %r13d
movl -0x4(%r12,%r13), %edx
xorl %edi, %edx
cmpl $0x1, %edx
jne 0xce326
orb $-0x80, 0x3(%r12,%r13)
addq $0x18, %r13
cmpq %r13, %r11
jne 0xce314
incq %r10
cmpq %r8, %r10
jne 0xce2ae
movl $0x1, %edi
testb $0x1, %sil
movl $0x0, %esi
jne 0xce284
movq 0x78(%rsp), %rsi
movl 0x34(%rsp), %ebp
incl %eax
cmpq %rax, %rsi
ja 0xce25d
cmpl $0xb, 0x18(%rsp)
setne %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0xce397
movq 0x20(%rbx), %rax
movq 0x88(%rsp), %rcx
xorl %edx, %edx
movl (%rcx,%rdx,4), %edi
shrl %edi
movb $0xb, 0x4(%rax,%rdi,8)
incq %rdx
movl %edx, %edi
cmpq %rdi, %rsi
ja 0xce383
movq 0x28(%rsp), %rax
incl %eax
movq %rax, 0x28(%rsp)
movq 0x20(%rsp), %r12
movl 0x10(%rsp), %r13d
movl $0x1c02, %esi           # imm = 0x1C02
jmp 0xcdfb0
movq 0x28(%rsp), %r14
testl %r14d, %r14d
je 0xce3cb
movq %rbx, %rdi
callq 0xa0a7d
jmp 0xce3ce
xorl %r14d, %r14d
movq 0x88(%rsp), %rdi
callq 0x2220
movq 0x168(%rsp), %rdi
callq 0x2220
movq 0xf8(%rsp), %rdi
callq 0x2220
movl %r14d, %eax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq