// File: 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
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x1d0, %rsp            # imm = 0x1D0
movl 0x28(%rbp), %eax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movl %edx, -0x24(%rbp)
movl %ecx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movq %r9, -0x38(%rbp)
callq 0x2510
movsd %xmm0, -0x40(%rbp)
movq -0x18(%rbp), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
shll %eax
movl %eax, -0x44(%rbp)
movl $0x0, -0x54(%rbp)
movl $0xffffffff, -0x6c(%rbp) # imm = 0xFFFFFFFF
movq $0x0, -0x78(%rbp)
cmpl $0x1, -0x28(%rbp)
jne 0x116951
movl $0x2, -0x6c(%rbp)
cmpl $0x2, -0x28(%rbp)
jne 0x11695e
movl $0x1, -0x6c(%rbp)
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x2100
leaq -0x148(%rbp), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x2100
leaq -0x1b0(%rbp), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x2100
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
cmpl -0x44(%rbp), %eax
jae 0x116d7a
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movl (%rax,%rcx,8), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
jne 0x1169dd
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0x1, %eax
jne 0x1169e2
jmp 0x116d6c
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xb, %eax
je 0x116a2d
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xc, %eax
je 0x116a2d
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0xa, %eax
jne 0x116a32
jmp 0x116d6c
movq -0x18(%rbp), %rdi
movl -0x48(%rbp), %esi
xorl $0x1, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x166b50
cmpl $0x0, %eax
je 0x116a4f
jmp 0x116d6c
movq -0x18(%rbp), %rdi
movl -0x48(%rbp), %esi
movl -0x24(%rbp), %r8d
leaq -0x4c(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
callq 0x167340
movl %eax, -0x5c(%rbp)
cmpl $0x7, -0x5c(%rbp)
je 0x116a79
cmpl $0x0, -0x5c(%rbp)
jne 0x116a7e
jmp 0x116d6c
cmpl $0x0, -0x2c(%rbp)
je 0x116a8f
cmpl $0x4, -0x5c(%rbp)
jne 0x116a8f
jmp 0x116d6c
cmpq $0x0, -0x20(%rbp)
je 0x116af3
movl $0x0, -0x58(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0xa8(%rbp), %rax
jae 0x116ae4
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x98(%rbp), %rcx
movl -0x50(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shrl %ecx
movl %ecx, %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
addl -0x58(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x116aa4
movl -0x58(%rbp), %eax
cmpl -0x24(%rbp), %eax
jbe 0x116af1
jmp 0x116d6c
jmp 0x116af3
movl $0xa, -0x64(%rbp)
cmpl $0x5, -0x5c(%rbp)
jne 0x116b38
movq -0x20(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
movss 0x26fd89(%rip), %xmm0   # 0x38689c
callq 0x1166e0
movl %eax, -0x68(%rbp)
cmpl $0x1, -0x68(%rbp)
je 0x116b27
cmpl $0x2, -0x68(%rbp)
jne 0x116b36
movl -0x68(%rbp), %eax
cmpl -0x6c(%rbp), %eax
je 0x116b36
movl $0xb, -0x64(%rbp)
jmp 0x116b38
cmpl $0x3, -0x5c(%rbp)
jne 0x116cad
movq -0x18(%rbp), %rdi
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rcx
subq $0x1, %rcx
movl (%rax,%rcx,4), %esi
leaq -0x4c(%rbp), %rdx
callq 0x166b50
movl -0x4c(%rbp), %eax
xorl $0x1, %eax
movl %eax, -0x4c(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x18(%rbp), %rcx
movq 0x28(%rcx), %rcx
movl -0x4c(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movl -0x4c(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0x70(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x70(%rbp), %eax
jae 0x116cab
cmpl $0xb, -0x64(%rbp)
jne 0x116bc3
jmp 0x116cab
movq -0x78(%rbp), %rax
movl -0x50(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
je 0x116be1
jmp 0x116c9d
movq -0x78(%rbp), %rax
movl -0x50(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movq -0x98(%rbp), %rcx
movq -0xa8(%rbp), %rdx
subq $0x1, %rdx
movl (%rcx,%rdx,4), %ecx
xorl $0x1, %ecx
cmpl %ecx, %eax
jne 0x116c13
jmp 0x116c9d
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rcx
subq $0x1, %rcx
movl (%rax,%rcx,4), %ecx
xorl $0x1, %ecx
movq -0x78(%rbp), %rax
movl -0x50(%rbp), %r8d
imulq $0x18, %r8, %r8
addq %r8, %rax
movl 0x8(%rax), %r8d
movq 0x10(%rbp), %r9
movq 0x18(%rbp), %r11
movq 0x20(%rbp), %r10
movl 0x28(%rbp), %eax
leaq -0x148(%rbp), %r14
leaq -0x1b0(%rbp), %rbx
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movl %eax, 0x20(%rsp)
movl $0x1, 0x28(%rsp)
callq 0x1674d0
movl %eax, -0x60(%rbp)
cmpl $0x1, -0x60(%rbp)
jne 0x116c9b
movl $0xb, -0x64(%rbp)
jmp 0x116c9d
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x116bac
jmp 0x116cad
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0xa8(%rbp), %rax
jae 0x116ce9
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x98(%rbp), %rcx
movl -0x50(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shrl %ecx
movl %ecx, %ecx
movb $0x1, 0x4(%rax,%rcx,8)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x116cb4
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0xa8(%rbp), %rax
jae 0x116d1f
movq -0x18(%rbp), %rdi
movq -0x98(%rbp), %rax
movl -0x50(%rbp), %ecx
movl (%rax,%rcx,4), %esi
shrl %esi
callq 0xf6800
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x116cf0
cmpl $0xb, -0x64(%rbp)
jne 0x116d63
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0xa8(%rbp), %rax
jae 0x116d61
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x98(%rbp), %rcx
movl -0x50(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shrl %ecx
movl %ecx, %ecx
movb $0xb, 0x4(%rax,%rcx,8)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x116d2c
jmp 0x116d63
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x11699e
cmpl $0x0, -0x54(%rbp)
jbe 0x116d89
movq -0x18(%rbp), %rdi
callq 0xcdd10
movq -0x98(%rbp), %rdi
callq 0x2210
movq -0x100(%rbp), %rdi
callq 0x2210
movq -0x168(%rbp), %rdi
callq 0x2210
movl -0x54(%rbp), %eax
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbx
popq %r14
popq %rbp
retq
nopl (%rax)