// File: 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
movq %rsp, %rbp
pushq %rbx
subq $0x98, %rsp
movq 0x78(%rbp), %rax
movq 0x70(%rbp), %rax
movl 0x68(%rbp), %eax
movl 0x60(%rbp), %eax
movl 0x58(%rbp), %eax
movl 0x50(%rbp), %eax
movl 0x48(%rbp), %eax
movl 0x40(%rbp), %eax
movl 0x38(%rbp), %eax
movl 0x30(%rbp), %eax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movss %xmm0, -0x3c(%rbp)
movss %xmm1, -0x40(%rbp)
movss %xmm2, -0x44(%rbp)
movss %xmm3, -0x48(%rbp)
movss %xmm4, -0x4c(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movl $0x1, -0x64(%rbp)
movq -0x10(%rbp), %rdi
movl 0x50(%rbp), %edx
movq 0x70(%rbp), %r8
movq -0x60(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %r9d
movl $0x5, %ecx
movq %r9, %rsi
movl $0x1, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x11c760
cmpq $0x0, -0x60(%rbp)
jne 0x11c34e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl 0x58(%rbp), %r8d
movl 0x60(%rbp), %r9d
movl 0x68(%rbp), %r10d
movq 0x78(%rbp), %rax
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x11bb20
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x30(%rbp), %r9
movq 0x18(%rbp), %r10
movl 0x50(%rbp), %eax
movss -0x4c(%rbp), %xmm0
movq $0x2, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
callq 0x118970
cmpl $0x0, 0x48(%rbp)
jne 0x11c3d4
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x38(%rbp), %rax
movl %eax, %edx
movl 0x50(%rbp), %ecx
movq -0x18(%rbp), %r9
movq -0x30(%rbp), %r11
movq 0x18(%rbp), %r10
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %rax
xorl %r8d, %r8d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movl $0x2, 0x18(%rsp)
callq 0x1168e0
movq -0x58(%rbp), %rdi
callq 0x116380
movq %rax, -0x70(%rbp)
movq $0x0, -0x78(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x11c5a4
movq -0x58(%rbp), %rdi
callq 0x116380
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movl 0x50(%rbp), %edx
movq 0x70(%rbp), %r8
movq -0x60(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %r9d
movl $0x5, %ecx
movq %r9, %rsi
movl $0x1, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x11c760
cmpl $0x0, 0x48(%rbp)
jne 0x11c592
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r8
movss -0x3c(%rbp), %xmm0
movl 0x50(%rbp), %r10d
movq 0x70(%rbp), %rax
movl $0x2, %r9d
xorl %r11d, %r11d
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
callq 0x116eb0
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r9
movl 0x50(%rbp), %r10d
movq 0x70(%rbp), %rax
movl $0x2, %r8d
xorl %r11d, %r11d
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
callq 0x117ee0
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r8
movss -0x3c(%rbp), %xmm0
movq 0x10(%rbp), %rax
movl %eax, %r11d
movq 0x70(%rbp), %r10
movl 0x50(%rbp), %eax
movl $0x2, %r9d
xorl %ebx, %ebx
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movl %eax, 0x18(%rsp)
callq 0x117510
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r9
movq 0x10(%rbp), %rax
movl %eax, %r11d
movq 0x70(%rbp), %r10
movl 0x50(%rbp), %eax
movl $0x2, %r8d
xorl %ebx, %ebx
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movl %eax, 0x18(%rsp)
callq 0x118f40
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x10(%rbp), %rax
movl %eax, %r9d
movss -0x44(%rbp), %xmm0
movq 0x18(%rbp), %r10
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %rax
movl $0x2, %r8d
xorl %r11d, %r11d
movq %r10, (%rsp)
movq $0x0, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x1195b0
movq -0x58(%rbp), %rdi
callq 0x116380
movq %rax, -0x78(%rbp)
jmp 0x11c3e9
cmpl $0x0, 0x48(%rbp)
jne 0x11c5f0
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x38(%rbp), %rax
movl %eax, %edx
movl 0x50(%rbp), %ecx
movq -0x18(%rbp), %r9
movq -0x30(%rbp), %r11
movq 0x18(%rbp), %r10
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %rax
xorl %r8d, %r8d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movl $0x2, 0x18(%rsp)
callq 0x1168e0
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x30(%rbp), %r9
movq 0x18(%rbp), %r10
movl 0x50(%rbp), %eax
movss -0x4c(%rbp), %xmm0
movq $0x2, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
callq 0x118970
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq 0x18(%rbp), %r9
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %r10
movl 0x50(%rbp), %eax
movss -0x48(%rbp), %xmm2
movl $0x14, %ecx
movl $0x64, %r8d
movss 0x26a244(%rip), %xmm0   # 0x3868a4
movss 0x262a04(%rip), %xmm1   # 0x37f06c
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x11cca0
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r8
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %r9
callq 0x11d700
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl 0x50(%rbp), %eax
movb %al, %r8b
movss -0x4c(%rbp), %xmm0
movq -0x30(%rbp), %r9
movq 0x18(%rbp), %r11
movq 0x70(%rbp), %rax
movq 0xa0(%rax), %r10
leaq 0x2a812a(%rip), %rax    # 0x3c47f8
movl 0x1c0(%rax), %eax
movss 0x26a1bc(%rip), %xmm1   # 0x386898
movzbl %r8b, %r8d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
callq 0x11d9e0
cmpl $0x0, -0x64(%rbp)
je 0x11c716
movl $0x0, -0x64(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movss -0x48(%rbp), %xmm0
callq 0xde540
jmp 0x11c2e8
cmpq $0x0, -0x60(%rbp)
je 0x11c755
movq 0x2a78bc(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x60(%rbp), %rax
movl 0x40(%rax), %ecx
leaq 0x26bad7(%rip), %rsi    # 0x38820c
leaq 0x26baed(%rip), %rdx    # 0x388229
movb $0x0, %al
callq 0x22a0
movq -0x60(%rbp), %rdi
callq 0x11bc30
movq -0x60(%rbp), %rdi
callq 0x2210
addq $0x98, %rsp
popq %rbx
popq %rbp
retq
nop