// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Overlaps.cpp
// Function: clean_trio_untig_graph(ma_ug_t*, asg_t*, ma_sub_t*, ma_hit_t_alloc*, ma_hit_t_alloc*, long long, float, long long, R_to_U*, buf_t*, unsigned char*, float, unsigned int, unsigned int, float, int, int, float, unsigned int, float, int, int, int, hap_cov_t*, kvec_asg_arc_t_warp*)
void clean_trio_untig_graph(ma_ug_t *ug, asg_t *read_g, ma_sub_t* coverage_cut, 
ma_hit_t_alloc* sources, ma_hit_t_alloc* reverse_sources, 
long long tipsLen, float tip_drop_ratio, long long stops_threshold, 
R_to_U* ruIndex, buf_t* b_0, uint8_t* visit, float density, uint32_t miniHapLen, 
uint32_t miniBiGraph, float chimeric_rate, int is_final_clean, int just_bubble_pop, 
float drop_ratio, uint32_t trio_flag, float trio_drop_rate, int max_hang, int min_ovlp, 
int gap_fuzz, hap_cov_t *cov, kvec_asg_arc_t_warp *ae)
{
    asg_t *g = ug->g; rd_hamming_fly_simp_t *p = NULL; 
    uint32_t is_first = 1;
    // if(trio_flag == MOTHER) {
    //     print_debug_gfa(read_g, ug, coverage_cut, "debug_dups", sources, ruIndex, asm_opt.max_hang_Len, asm_opt.min_overlap_Len, 0, 1, 0);
    //     exit(1);
    // }
    redo:
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-0:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-0:", 0);
    ///debug
    // if(!p) p = gen_rd_hamming_fly_simp_t(ug, read_g, sources, coverage_cut, max_hang, min_ovlp, gap_fuzz); 
    // fprintf(stderr, "[M::%s] 0\n", __func__); dbg_asys_gfa(g);
    asg_pop_bubble_primary_trio(ug, NULL, trio_flag, DROP, cov, NULL, 1, p);
    ///do not need to refine bubbles during the first round of cleaning
    if(!p) p = gen_rd_hamming_fly_simp_t(ug, read_g, sources, coverage_cut, max_hang, min_ovlp, gap_fuzz, ae); 

    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-1:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-1:", 0);
    // fprintf(stderr, "[M::%s] 1\n", __func__); dbg_asys_gfa(g);
    magic_trio_phasing(g, ug, read_g, coverage_cut, sources, reverse_sources, 2, ruIndex, trio_flag, trio_drop_rate);        
    // fprintf(stderr, "[M::%s] 2\n", __func__); dbg_asys_gfa(g);

    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-2:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-2:", 0);
    /**********debug**********/
    if(just_bubble_pop == 0)
    {
        cut_trio_tip_primary(g, ug, tipsLen, trio_flag, 0, read_g, reverse_sources, ruIndex, cov->is_r_het, 2);
    }
    // fprintf(stderr, "[M::%s] 3\n", __func__); dbg_asys_gfa(g);
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-3:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-3:", 0);
    /**********debug**********/
    long long pre_cons = get_graph_statistic(g);
    long long cur_cons = 0;
    while(pre_cons != cur_cons)
    {
        // fprintf(stderr, "[M::%s] 4\n", __func__); dbg_asys_gfa(g);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-4:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-4:", 0);
        pre_cons = get_graph_statistic(g);
        // fprintf(stderr, "[M::%s] 5\n", __func__); dbg_asys_gfa(g);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-5:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-5:", 0);
        ///need consider tangles
        asg_pop_bubble_primary_trio(ug, NULL, trio_flag, DROP, cov, NULL, 1, p);
        // fprintf(stderr, "[M::%s] 6\n", __func__); dbg_asys_gfa(g);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-6:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-6:", 0);
        /**********debug**********/
        if(just_bubble_pop == 0)
        {
            ///need consider tangles
            asg_arc_cut_trio_long_tip_primary(g, ug, read_g, reverse_sources, ruIndex, 2, tip_drop_ratio, trio_flag, cov, NULL);            
            // if(trio_flag == MOTHER) print_untig((ug), 9, "i-7:", 0);
            // if(trio_flag == MOTHER) print_untig((ug), 10, "i-7:", 0);
            // fprintf(stderr, "[M::%s] 7\n", __func__); dbg_asys_gfa(g);
            // if(trio_flag == MOTHER) print_debug_gfa(read_g, ug, coverage_cut, "debug_dups", sources, ruIndex, asm_opt.max_hang_Len, asm_opt.min_overlap_Len);
            asg_arc_cut_trio_long_equal_tips_assembly(g, ug, read_g, reverse_sources, 2, ruIndex, trio_flag, cov, NULL);            
            // if(trio_flag == MOTHER) print_untig((ug), 9, "i-8:", 0);
            // if(trio_flag == MOTHER) print_untig((ug), 10, "i-8:", 0);
            // fprintf(stderr, "[M::%s] 8\n", __func__); dbg_asys_gfa(g);
            asg_arc_cut_trio_long_tip_primary_complex(g, ug, read_g, reverse_sources, ruIndex, 2, tip_drop_ratio, stops_threshold, cov, NULL, trio_flag);
            // if(trio_flag == MOTHER) print_untig((ug), 9, "i-9:", 0);
            // if(trio_flag == MOTHER) print_untig((ug), 10, "i-9:", 0);
            // fprintf(stderr, "[M::%s] 9\n", __func__); dbg_asys_gfa(g);
            asg_arc_cut_trio_long_equal_tips_assembly_complex(g, ug, read_g, reverse_sources, 2, ruIndex, stops_threshold, cov, NULL, trio_flag);
            // if(trio_flag == MOTHER) print_untig((ug), 9, "i-10:", 0);
            // if(trio_flag == MOTHER) print_untig((ug), 10, "i-10:", 0);
            // fprintf(stderr, "[M::%s] 10\n", __func__); dbg_asys_gfa(g);
            detect_chimeric_by_topo(g, ug, read_g, reverse_sources, 2, stops_threshold, chimeric_rate, ruIndex, NULL, cov->is_r_het);
            // if(trio_flag == MOTHER) print_untig((ug), 9, "i-11:", 0);
            // if(trio_flag == MOTHER) print_untig((ug), 10, "i-11:", 0);
            // fprintf(stderr, "[M::%s] 11\n", __func__); dbg_asys_gfa(g);
            ///need consider tangles
            ///note we need both the read graph and the untig graph
        }
        /**********debug**********/
        cur_cons = get_graph_statistic(g);
        // fprintf(stderr, "[M::%s] 12\n", __func__); dbg_asys_gfa(g);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-12:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-12:", 0);
    }
    if(just_bubble_pop == 0)
    {   
        // fprintf(stderr, "[M::%s] 13\n", __func__); dbg_asys_gfa(g);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-13:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-13:", 0);
        cut_trio_tip_primary(g, ug, tipsLen, trio_flag, 0, read_g, reverse_sources, ruIndex, cov->is_r_het, 2);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-14:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-14:", 0);
        // fprintf(stderr, "[M::%s] 14\n", __func__); dbg_asys_gfa(g);
    }

    // print_debug_gfa(read_g, ug, coverage_cut, "debug_dups", sources, ruIndex, asm_opt.max_hang_Len, asm_opt.min_overlap_Len);
    // fprintf(stderr, "[M::%s] 15\n", __func__); dbg_asys_gfa(g);
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-15:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-15:", 0);
    magic_trio_phasing(g, ug, read_g, coverage_cut, sources, reverse_sources, 2, ruIndex, trio_flag, trio_drop_rate); 
    // fprintf(stderr, "[M::%s] 16\n", __func__); dbg_asys_gfa(g);
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-16:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-16:", 0);

    // print_debug_gfa(read_g, ug, coverage_cut, "resolve_tangles", sources, ruIndex, asm_opt.max_hang_Len, asm_opt.min_overlap_Len, 0, 0, 0);
    // exit(1);
    ///bug here
    resolve_tangles(ug, read_g, reverse_sources, 20, 100, 0.05, 0.2, ruIndex, cov->is_r_het, trio_flag, drop_ratio);    
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-17:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-17:", 0);
    // fprintf(stderr, "[M::%s] 17\n", __func__); dbg_asys_gfa(g);
    drop_semi_circle(ug, g, read_g, reverse_sources, ruIndex, cov->is_r_het);
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-18:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-18:", 0);
    // fprintf(stderr, "[M::%s] 18\n", __func__); dbg_asys_gfa(g);
    all_to_all_deduplicate(ug, read_g, coverage_cut, sources, trio_flag, trio_drop_rate, reverse_sources, ruIndex, cov->is_r_het, DOUBLE_CHECK_THRES, asm_opt.trio_flag_occ_thres);
    // if(trio_flag == MOTHER) print_untig((ug), 9, "i-19:", 0);
    // if(trio_flag == MOTHER) print_untig((ug), 10, "i-19:", 0);
    // fprintf(stderr, "[M::%s] 19\n", __func__); dbg_asys_gfa(g);
    // if(trio_flag == MOTHER) print_untig_by_read(ug, "m54329U_190827_173812/30214441/ccs", (uint32_t)-1, NULL, NULL, "bf-16");
    if(is_first)
    {
        is_first = 0;
        unitig_arc_del_short_diploid_by_length(ug->g, drop_ratio);
        // if(trio_flag == MOTHER) print_untig((ug), 9, "i-20:", 0);
        // if(trio_flag == MOTHER) print_untig((ug), 10, "i-20:", 0);
        // fprintf(stderr, "[M::%s] 20\n", __func__); dbg_asys_gfa(g);
        goto redo;
    } 
    if(p) {
        fprintf(stderr, "[M::%s] # adjusted arcs::%u\n", __func__, p->n_insert);
        destroy_rd_hamming_fly_simp_t(p); free(p);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movss %xmm4, 0xc(%rsp)
movss %xmm3, 0x18(%rsp)
movss %xmm2, 0x3c(%rsp)
movss %xmm0, 0x1c(%rsp)
movq %r9, 0x40(%rsp)
movq %r8, 0x28(%rsp)
movq %rcx, %r15
movq %rdx, 0x20(%rsp)
movq %rsi, 0x10(%rsp)
movq %rdi, %rbp
movl 0xd0(%rsp), %ebx
movl 0xc8(%rsp), %r14d
movq 0x18(%rdi), %r12
movzbl %bl, %eax
movl %eax, 0x38(%rsp)
xorl %r13d, %r13d
movq $0x0, 0x48(%rsp)
movq %r12, (%rsp)
movq %rcx, 0x50(%rsp)
movq %rbp, %rdi
xorl %esi, %esi
movl %ebx, %edx
movl $0x5, %ecx
movq 0xf0(%rsp), %r8
xorl %r9d, %r9d
pushq %r13
pushq $0x1
callq 0xd3845
addq $0x10, %rsp
testq %r13, %r13
jne 0xd34ab
movq %rbp, %rdi
movq 0x10(%rsp), %rsi
movq %r15, %rdx
movq 0x20(%rsp), %rcx
movl 0xd8(%rsp), %r8d
movl 0xe0(%rsp), %r9d
pushq 0xf8(%rsp)
movl 0xf0(%rsp), %eax
pushq %rax
callq 0xd30f6
addq $0x10, %rsp
movq %rax, %r13
subq $0x20, %rsp
movl %ebx, 0x10(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0x8(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
movq 0x30(%rsp), %rdx
movq 0x40(%rsp), %rcx
movq %r15, %r8
movss 0x2c(%rsp), %xmm0
callq 0xd0207
addq $0x20, %rsp
testl %r14d, %r14d
jne 0xd3520
movq %r12, %rdi
movq %rbp, %rsi
movq 0x40(%rsp), %rdx
movl %ebx, %ecx
xorl %r8d, %r8d
movq 0x10(%rsp), %r9
pushq $0x2
movq 0xf8(%rsp), %rax
pushq 0xa0(%rax)
pushq 0xa8(%rsp)
pushq 0x40(%rsp)
callq 0xcde83
addq $0x20, %rsp
movq %r12, %rdi
callq 0xcdba4
testq %rax, %rax
movq 0xf0(%rsp), %rbx
movq %r13, 0x30(%rsp)
je 0xd36b3
movq %r12, %rdi
callq 0xcdba4
movq %rax, %r15
movq %rbp, %rdi
xorl %esi, %esi
movl 0xd0(%rsp), %edx
movl $0x5, %ecx
movq %rbx, %r8
xorl %r9d, %r9d
pushq %r13
pushq $0x1
callq 0xd3845
addq $0x10, %rsp
testl %r14d, %r14d
jne 0xd36a2
subq $0x8, %rsp
movq %r12, %rdi
movq %rbp, %rsi
movq %rbp, %r12
movq 0x18(%rsp), %rbp
movq %rbp, %rdx
movq 0x30(%rsp), %r14
movq %r14, %rcx
movq 0xa0(%rsp), %r13
movq %r13, %r8
movl $0x2, %r9d
movss 0x24(%rsp), %xmm0
xorl %eax, %eax
pushq %rax
pushq %rbx
movl 0xe8(%rsp), %ebx
pushq %rbx
callq 0xce4b6
addq $0x18, %rsp
movl $0x2, %r8d
movq 0x8(%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
movq %r14, %rcx
movq %r13, %r9
xorl %eax, %eax
pushq %rax
pushq 0x100(%rsp)
pushq %rbx
callq 0xcf74c
addq $0x20, %rsp
movq (%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
movq %r14, %rcx
movq %r13, %r8
movl $0x2, %r9d
movss 0x1c(%rsp), %xmm0
pushq %rbx
xorl %eax, %eax
pushq %rax
pushq 0x100(%rsp)
movl 0xa8(%rsp), %r13d
pushq %r13
callq 0xcec2a
addq $0x20, %rsp
movl $0x2, %r8d
movq (%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
movq %r14, %rcx
movq 0x98(%rsp), %r9
pushq %rbx
movq 0xf8(%rsp), %rbx
xorl %eax, %eax
pushq %rax
pushq %rbx
pushq %r13
callq 0xd06a0
addq $0x18, %rsp
movl $0x2, %r8d
movq 0x8(%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
movq %r12, %rbp
movq 0x8(%rsp), %r12
movq %r14, %rcx
movl 0xd0(%rsp), %r14d
movl %r13d, %r9d
movq 0x38(%rsp), %r13
movss 0x44(%rsp), %xmm0
pushq 0xa0(%rbx)
xorl %eax, %eax
pushq %rax
pushq 0xb0(%rsp)
callq 0xd0f5e
addq $0x20, %rsp
movq %r12, %rdi
callq 0xcdba4
cmpq %rax, %r15
jne 0xd353e
testl %r14d, %r14d
movl 0xd0(%rsp), %r15d
jne 0xd36f2
movq %r12, %rdi
movq %rbp, %rsi
movq 0x40(%rsp), %rdx
movl %r15d, %ecx
xorl %r8d, %r8d
movq 0x10(%rsp), %r9
pushq $0x2
pushq 0xa0(%rbx)
pushq 0xa8(%rsp)
pushq 0x40(%rsp)
callq 0xcde83
addq $0x20, %rsp
subq $0x20, %rsp
movl %r15d, 0x10(%rsp)
movq 0xb8(%rsp), %rbx
movq %rbx, 0x8(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
movq %rbp, %r12
movq 0x30(%rsp), %rbp
movq %rbp, %rdx
movq %r15, %r13
movq 0x40(%rsp), %rcx
movq 0x70(%rsp), %r15
movq %r15, %r8
movss 0x2c(%rsp), %xmm0
callq 0xd0207
addq $0x20, %rsp
movl $0x14, %ecx
movl $0x64, %r8d
movq %r12, %rdi
movq %rbp, %rsi
movq 0x28(%rsp), %r14
movq %r14, %rdx
movss 0x162663(%rip), %xmm0   # 0x235dbc
movss 0x16265f(%rip), %xmm1   # 0x235dc0
movq %rbx, %r9
movss 0x18(%rsp), %xmm2
pushq %r13
movq 0xf8(%rsp), %r13
pushq 0xa0(%r13)
callq 0xd3be6
addq $0x10, %rsp
movq 0xa0(%r13), %r9
movq %r12, %rdi
movq (%rsp), %rsi
movq %rbp, %rdx
movq %r14, %rcx
movq %rbx, %r8
callq 0xd4320
leaq 0x1c1fb1(%rip), %rax    # 0x295758
movl 0x1c0(%rax), %eax
subq $0x8, %rsp
movq %r12, %rdi
movq %rbp, %rsi
movq 0x28(%rsp), %rdx
movq %r15, %rcx
movl 0x40(%rsp), %r8d
movss 0x14(%rsp), %xmm0
movq %r14, %r9
movss 0x1625db(%rip), %xmm1   # 0x235db0
pushq %rax
pushq 0xa0(%r13)
pushq %rbx
callq 0xd46b6
addq $0x20, %rsp
testb $0x1, 0x48(%rsp)
jne 0xd3825
movq 0x18(%r12), %rdi
movss 0x18(%rsp), %xmm0
callq 0xac5b4
movb $0x1, %al
movq %rax, 0x48(%rsp)
movl 0xd0(%rsp), %ebx
movl 0xc8(%rsp), %r14d
movq %r12, %rbp
movq (%rsp), %r12
movq 0x30(%rsp), %r13
jmp 0xd3447
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
jne 0xd383e
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x10e69
jmp 0xd382f