// File: /workspace/github_cpp_makefile_star2_O1/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, %r13d
movl %ecx, %ebp
movl %edx, 0x14(%rsp)
movq %rsi, 0x18(%rsp)
movq %rdi, %rbx
callq 0x300fc
movl 0x14(%rbx), %r8d
addl %r8d, %r8d
xorl %eax, %eax
cmpl $0x1, %ebp
sete %al
leal (%rax,%rax,2), %eax
decl %eax
cmpl $0x2, %ebp
movl $0x1, %ecx
cmovnel %eax, %ecx
movl %ecx, 0x34(%rsp)
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 %eax, %eax
movq %rax, 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 %rax, 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 $0x0, 0x20(%rsp)
movq %rax, 0x110(%rsp)
testl %r8d, %r8d
je 0xcd0ac
xorl %r14d, %r14d
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl $0x1c02, %r9d           # imm = 0x1C02
movq $0x0, 0x20(%rsp)
movl %r8d, 0xc(%rsp)
movq 0x20(%rbx), %rax
movl %r14d, %ecx
shrl %ecx
cmpl $0x0, (%rax,%rcx,8)
js 0xcccb4
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xc, %eax
ja 0xcccc1
btl %eax, %r9d
jae 0xcccc1
incl %r14d
cmpl %r8d, %r14d
jne 0xccc95
jmp 0xcd0ac
movl %r14d, %eax
xorl $0x1, %eax
movq 0x28(%rbx), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, %rcx
andq %r15, %rcx
je 0xccd0e
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 0xcccf7
testl %esi, %esi
jne 0xcccb4
movq %rbx, %rdi
movl %r14d, %esi
leaq 0x10(%rsp), %rdx
leaq 0x40(%rsp), %rcx
movl 0x14(%rsp), %r8d
callq 0x1013f1
testl %eax, %eax
je 0xcd09c
movl %eax, %ebp
cmpl $0x7, %eax
je 0xcd09c
testl %r13d, %r13d
setne %al
cmpl $0x4, %ebp
sete %cl
testb %cl, %al
jne 0xcd09c
cmpq $0x0, 0x18(%rsp)
je 0xccd9f
movq 0x78(%rsp), %rax
testq %rax, %rax
je 0xccd93
movq 0x18(%rsp), %rcx
movq 0x10(%rcx), %rcx
xorl %esi, %esi
movq 0x88(%rsp), %rdi
xorl %edx, %edx
movl (%rdi,%rsi,4), %r8d
shrl %r8d
leaq (%r8,%r8,4), %r8
addl 0x4(%rcx,%r8,8), %edx
incq %rsi
movl %esi, %r8d
cmpq %r8, %rax
ja 0xccd76
jmp 0xccd95
xorl %edx, %edx
cmpl 0x14(%rsp), %edx
ja 0xcd09c
movl $0xa, %edx
cmpl $0x5, %ebp
jne 0xccdd4
leaq 0x40(%rsp), %rdi
movq 0x18(%rsp), %rsi
movss 0x15ce01(%rip), %xmm0   # 0x229bbc
callq 0xcca71
testl %eax, %eax
sete %cl
cmpl 0x34(%rsp), %eax
sete %al
orb %cl, %al
movzbl %al, %edx
xorl $0xb, %edx
cmpl $0x3, %ebp
movl %r13d, 0x30(%rsp)
jne 0xccf12
movq 0x78(%rsp), %rax
movq 0x88(%rsp), %rcx
movl -0x4(%rcx,%rax,4), %ecx
movq 0x28(%rbx), %rax
movq (%rax,%rcx,8), %rsi
movq %rsi, %rcx
andq %r15, %rcx
je 0xcce3a
movq 0x8(%rbx), %rdi
shrq $0x20, %rsi
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rsi,%rsi,2), %rsi
leaq (%rdi,%rsi,8), %rsi
addq $0xc, %rsi
xorl %edi, %edi
cmpl $0x0, (%rsi,%rdi)
js 0xcce31
movl -0x4(%rsi,%rdi), %r8d
movl %r8d, 0x10(%rsp)
addq $0x18, %rdi
cmpq %rdi, %rcx
jne 0xcce21
movl 0x10(%rsp), %ecx
xorq $0x1, %rcx
movl %ecx, 0x10(%rsp)
cmpl $0xb, %edx
je 0xccf12
movq (%rax,%rcx,8), %rax
movl %eax, %ecx
testq %rcx, %rcx
je 0xccf12
movq 0x8(%rbx), %rcx
movq %rax, %rdx
shrq $0x20, %rdx
movl %eax, %r12d
leaq (%rdx,%rdx,2), %rax
leaq (%rcx,%rax,8), %r13
addq $0xc, %r13
movl $0x1, %ebp
movl $0xa, %edx
cmpl $0x0, (%r13)
js 0xccef9
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 0xccef9
movq %rbx, %rdi
movq 0x18(%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 0x1015d1
addq $0x30, %rsp
xorl %edx, %edx
cmpl $0x1, %eax
sete %dl
orl $0xa, %edx
cmpl $0xb, %edx
je 0xccf12
addq $0x18, %r13
leaq 0x1(%rbp), %rax
cmpq %r12, %rbp
movq %rax, %rbp
jb 0xcce7d
movl %edx, 0x2c(%rsp)
movq 0x78(%rsp), %rax
testq %rax, %rax
je 0xccf46
movq 0x20(%rbx), %rcx
movq 0x88(%rsp), %rsi
xorl %edi, %edi
movl (%rsi,%rdi,4), %r8d
shrl %r8d
movb $0x1, 0x4(%rcx,%r8,8)
incq %rdi
movl %edi, %r8d
cmpq %r8, %rax
ja 0xccf2e
movq 0x78(%rsp), %rcx
testq %rcx, %rcx
je 0xcd057
xorl %eax, %eax
movq 0x88(%rsp), %rcx
movl (%rcx,%rax,4), %ecx
movl %ecx, %esi
shrl %esi
movq 0x20(%rbx), %rdi
cmpb $0x1, 0x4(%rdi,%rsi,8)
jne 0xcd047
andl $-0x2, %ecx
xorl %esi, %esi
leaq (%rsi,%rcx), %rdi
movq 0x28(%rbx), %r8
movq (%r8,%rdi,8), %r9
movq %r9, %r8
andq %r15, %r8
je 0xcd037
shrq $0x20, %r9
leaq (%r9,%r9,2), %r9
shlq $0x3, %r9
addq 0x8(%rbx), %r9
xorl %r10d, %r10d
leaq (%r10,%r10,2), %r13
movl 0xc(%r9,%r13,8), %r11d
testl %r11d, %r11d
js 0xcd02b
leaq (%r9,%r13,8), %rbp
movq 0x20(%rbx), %rdx
movl 0x8(%rbp), %r12d
movl %r12d, %r13d
shrl %r13d
cmpb $0x1, 0x4(%rdx,%r13,8)
je 0xcd02b
orl $0x80000000, %r11d      # imm = 0x80000000
movl %r11d, 0xc(%rbp)
xorq $0x1, %r12
movq 0x28(%rbx), %rdx
movq (%rdx,%r12,8), %r13
movq %r13, %r11
andq %r15, %r11
je 0xcd02b
movq 0x8(%rbx), %rdx
shrq $0x20, %r13
shlq $0x3, %r11
leaq (%r11,%r11,2), %r11
leaq (,%r13,2), %r12
addq %r13, %r12
leaq (%rdx,%r12,8), %r13
addq $0xc, %r13
xorl %ebp, %ebp
movl -0x4(%r13,%rbp), %edx
xorl %edi, %edx
cmpl $0x1, %edx
jne 0xcd022
orb $-0x80, 0x3(%r13,%rbp)
addq $0x18, %rbp
cmpq %rbp, %r11
jne 0xcd010
incq %r10
cmpq %r8, %r10
jne 0xccfa4
leaq 0x1(%rsi), %rdx
testq %rsi, %rsi
movq %rdx, %rsi
je 0xccf79
incl %eax
movq 0x78(%rsp), %rcx
cmpq %rax, %rcx
ja 0xccf56
cmpl $0xb, 0x2c(%rsp)
setne %al
testq %rcx, %rcx
sete %dl
orb %al, %dl
jne 0xcd08b
movq 0x20(%rbx), %rax
movq 0x88(%rsp), %rdx
xorl %esi, %esi
movl (%rdx,%rsi,4), %edi
shrl %edi
movb $0xb, 0x4(%rax,%rdi,8)
incq %rsi
movl %esi, %edi
cmpq %rdi, %rcx
ja 0xcd077
movq 0x20(%rsp), %rax
incl %eax
movq %rax, 0x20(%rsp)
movl 0x30(%rsp), %r13d
movl 0xc(%rsp), %r8d
movl $0x1c02, %r9d           # imm = 0x1C02
jmp 0xcccb4
movq 0x20(%rsp), %r14
testl %r14d, %r14d
je 0xcd0be
movq %rbx, %rdi
callq 0xa02fa
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