// File: /workspace/github_cpp_makefile_star2_O2/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 $0x178, %rsp            # imm = 0x178
movq %r9, %r12
movl %r8d, %r13d
movl %ecx, %ebp
movl %edx, %r14d
movq %rsi, 0x8(%rsp)
movq %rdi, %rbx
callq 0x251c
movl 0x14(%rbx), %r15d
addl %r15d, %r15d
xorl %eax, %eax
cmpl $0x1, %ebp
sete %al
leal (%rax,%rax,2), %eax
decl %eax
cmpl $0x2, %ebp
movl %r14d, %ebp
pushq $0x1
popq %rcx
cmovnel %eax, %ecx
movl %ecx, 0x24(%rsp)
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rax
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movaps %xmm0, 0x30(%rax)
andq $0x0, 0x60(%rax)
movaps %xmm0, 0x40(%rax)
movaps %xmm0, 0x50(%rax)
leaq 0x110(%rsp), %rax
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movaps %xmm0, 0x30(%rax)
movaps %xmm0, 0x40(%rax)
movaps %xmm0, 0x50(%rax)
andq $0x0, 0x60(%rax)
leaq 0xa0(%rsp), %rax
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movaps %xmm0, 0x30(%rax)
andq $0x0, 0x60(%rax)
movaps %xmm0, 0x40(%rax)
movaps %xmm0, 0x50(%rax)
movq $0x0, 0x10(%rsp)
movl $0x1c02, %edx           # imm = 0x1C02
xorl %r14d, %r14d
cmpl %r15d, %r14d
je 0x93351
movq 0x20(%rbx), %rax
movl %r14d, %ecx
shrl %ecx
cmpl $0x0, (%rax,%rcx,8)
js 0x930f6
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xc, %eax
ja 0x930fb
btl %eax, %edx
jae 0x930fb
incl %r14d
jmp 0x930cf
movl %r14d, %esi
xorl $0x1, %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0xc2e7a
testl %eax, %eax
je 0x93116
movl $0x1c02, %edx           # imm = 0x1C02
jmp 0x930f6
movq %rbx, %rdi
movl %r14d, %esi
leaq 0x4(%rsp), %rdx
leaq 0x30(%rsp), %rcx
movl %ebp, %r8d
callq 0xc321b
testl %eax, %eax
je 0x9310f
cmpl $0x7, %eax
je 0x9310f
testl %r13d, %r13d
setne %cl
cmpl $0x4, %eax
sete %dl
testb %dl, %cl
jne 0x9310f
cmpq $0x0, 0x8(%rsp)
je 0x93185
movq 0x68(%rsp), %rcx
movq 0x78(%rsp), %rsi
xorl %edx, %edx
xorl %edi, %edi
movl %edi, %edi
cmpq %rdi, %rcx
jbe 0x93181
movq 0x8(%rsp), %r8
movq 0x10(%r8), %r8
movl (%rsi,%rdi,4), %r9d
shrl %r9d
imulq $0x28, %r9, %r9
addl 0x4(%r8,%r9), %edx
incl %edi
jmp 0x9315d
cmpl %ebp, %edx
ja 0x9310f
movl %ebp, 0x1c(%rsp)
movl %r13d, 0x20(%rsp)
movq %r12, 0x28(%rsp)
cmpl $0x3, %eax
je 0x93265
pushq $0xa
popq %r13
cmpl $0x5, %eax
jne 0x931d2
leaq 0x30(%rsp), %rdi
movq 0x8(%rsp), %rsi
movss 0x154afd(%rip), %xmm0   # 0x1e7cb4
callq 0x92f19
testl %eax, %eax
sete %cl
cmpl 0x24(%rsp), %eax
sete %al
orb %cl, %al
movzbl %al, %r13d
xorl $0xb, %r13d
movq 0x68(%rsp), %rax
movq 0x78(%rsp), %rcx
xorl %edx, %edx
movl %edx, %edx
cmpq %rdx, %rax
jbe 0x931f7
movq 0x20(%rbx), %rsi
movl (%rcx,%rdx,4), %edi
shrl %edi
movb $0x1, 0x4(%rsi,%rdi,8)
incl %edx
jmp 0x931de
xorl %ecx, %ecx
movl 0x1c(%rsp), %ebp
movl %ecx, %r12d
cmpq %r12, %rax
jbe 0x93224
movq 0x78(%rsp), %rax
movl (%rax,%r12,4), %esi
shrl %esi
movq %rbx, %rdi
callq 0x80870
leal 0x1(%r12), %ecx
movq 0x68(%rsp), %rax
jmp 0x931fd
cmpl $0xb, %r13d
movq 0x28(%rsp), %r12
movl 0x20(%rsp), %r13d
jne 0x93254
xorl %edx, %edx
movq 0x78(%rsp), %rcx
movl %edx, %edx
cmpq %rdx, %rax
jbe 0x93254
movq 0x20(%rbx), %rsi
movl (%rcx,%rdx,4), %edi
shrl %edi
movb $0xb, 0x4(%rsi,%rdi,8)
incl %edx
jmp 0x9323b
movq 0x10(%rsp), %rax
incl %eax
movq %rax, 0x10(%rsp)
jmp 0x9310f
movq 0x68(%rsp), %rax
movq 0x78(%rsp), %rcx
movl -0x4(%rcx,%rax,4), %esi
movq %rbx, %rdi
leaq 0x4(%rsp), %rdx
callq 0xc2e7a
movl 0x4(%rsp), %eax
xorq $0x1, %rax
movl %eax, 0x4(%rsp)
movq 0x8(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq (%rdx,%rax,8), %rax
movl %eax, %edx
shrq $0x20, %rax
imulq $0x18, %rax, %rax
leaq (%rcx,%rax), %r12
addq $0xc, %r12
xorl %ebp, %ebp
pushq $0xa
popq %r13
cmpl $0xb, %r13d
je 0x931d2
cmpq %rdx, %rbp
jae 0x931d2
cmpl $0x0, (%r12)
pushq $0xa
popq %r13
js 0x93345
movl -0x4(%r12), %r8d
movq 0x68(%rsp), %rax
movq 0x78(%rsp), %rcx
movl -0x4(%rcx,%rax,4), %ecx
xorl $0x1, %ecx
cmpl %ecx, %r8d
je 0x93345
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movq %rdx, %r13
movq 0x28(%rsp), %rdx
movq 0x1b0(%rsp), %r9
pushq $0x1
movl 0x1d0(%rsp), %eax
pushq %rax
pushq 0x1d0(%rsp)
pushq 0x1d0(%rsp)
leaq 0xc0(%rsp), %rax
pushq %rax
leaq 0x138(%rsp), %rax
pushq %rax
callq 0xc3307
movq %r13, %rdx
addq $0x30, %rsp
xorl %r13d, %r13d
cmpl $0x1, %eax
sete %r13b
orl $0xa, %r13d
incq %rbp
addq $0x18, %r12
jmp 0x932b0
movq 0x10(%rsp), %r14
testl %r14d, %r14d
je 0x93363
movq %rbx, %rdi
callq 0x694eb
movq 0x78(%rsp), %rdi
callq 0x2220
movq 0x158(%rsp), %rdi
callq 0x2220
movq 0xe8(%rsp), %rdi
callq 0x2220
movl %r14d, %eax
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq