// File: chhylp123[P]hifiasm/gfa_ut.cpp
// Function: u2g_clean(ul_resolve_t*, ulg_opt_t*, unsigned int, unsigned long)
void u2g_clean(ul_resolve_t *uidx, ulg_opt_t *ulopt, uint32_t keep_raw_utg, uint64_t is_bridg)
{
    ul2ul_idx_t *idx = &(uidx->uovl); asg64_v bu = {0,0,0}, uu = {0,0,0}; int64_t max_tip_hifi0 = ulopt->max_tip_hifi;
    ma_ug_t *iug = idx->i_ug; int64_t i, mm_tip = ulopt->max_tip; uint64_t cnt = 1, topo_level, ss = 0;
    double step = (ulopt->clean_round==1?ulopt->max_path_drop_ratio:
                        ((ulopt->max_path_drop_ratio-ulopt->min_path_drop_ratio)/(ulopt->clean_round-1)));
    double drop = ulopt->min_path_drop_ratio; CALLOC(iug->g->seq_vis, iug->g->n_seq*2);


    // char sb[1000]; 
    // output_integer_graph(uidx, iug, "ig_h0", 0);

    // fprintf(stderr, "\n[M::%s::] max_path_drop_ratio::%f, min_path_drop_ratio::%f, max_tip_hifi::%ld, max_tip::%ld\n", 
    // __func__, ulopt->max_path_drop_ratio, ulopt->min_path_drop_ratio, 
    // ulopt->max_tip_hifi, ulopt->max_tip);
    for (ss = 0; ss < 2; ss++) {
        for (i = 0, drop = ulopt->min_path_drop_ratio; i < ulopt->clean_round; i++, drop += step) {
            if(drop > ulopt->max_path_drop_ratio) drop = ulopt->max_path_drop_ratio;
            // fprintf(stderr, "[M::%s::] Starting round-%ld, drop::%f, max_tip_hifi::%ld\n", 
            // __func__, i, drop, ulopt->max_tip_hifi);
            cnt = 1; topo_level = 2; mm_tip = ulopt->max_tip;
            while (cnt) {
                cnt = 0;
                asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
                cnt += ulg_arc_cut_supports(uidx, iug, mm_tip, ulopt->max_tip_hifi, drop, ulopt->is_trio, topo_level, 1, NULL, keep_raw_utg, &bu, &uu);
                cnt += ulg_arc_cut_tips(uidx, iug, mm_tip, ulopt->max_tip_hifi, 1, &bu, &uu);///p_telo
            }
            
            cnt = 1; topo_level = 1; mm_tip = ulopt->max_tip;
            while (cnt) {
                cnt = 0;
                asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
                cnt += ulg_arc_cut_supports(uidx, iug, mm_tip, ulopt->max_tip_hifi, drop, ulopt->is_trio, topo_level, 1, NULL, keep_raw_utg, &bu, &uu);
                cnt += ulg_arc_cut_tips(uidx, iug, mm_tip, ulopt->max_tip_hifi, 1, &bu, &uu);
            }

            cnt = 1; topo_level = 1; mm_tip = ((int64_t)0x7fffffff);
            while (cnt) {
                cnt = 0;
                asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
                cnt += ulg_arc_cut_supports(uidx, iug, mm_tip, ulopt->max_tip_hifi, drop, ulopt->is_trio, topo_level, 1, NULL, keep_raw_utg, &bu, &uu);
                cnt += ulg_arc_cut_tips(uidx, iug, mm_tip, ulopt->max_tip_hifi, 0, &bu, &uu);
            }
            // fprintf(stderr, "[M::%s::] Done round-%ld, drop::%f\n", __func__, i, drop);
            // sprintf(sb, "ig_ss_%lu_i_%ld", ss, i);
            // output_integer_graph(uidx, iug, sb, 0);
        }

        ulg_pop_bubble(uidx, iug, NULL, ((int64_t)0x7fffffff), ulopt->max_tip_hifi, 1, &bu, &uu);

        while(ulg_arc_cut_z(uidx, iug, ((int64_t)0x7fffffff), ulopt->max_tip_hifi, 1.5, 0.15, 100, 0.8, ulopt->is_trio, 1, NULL, &bu, &uu));///non_p_telo

        // sprintf(sb, "ig_ss_%lu_i_%ld", ss, i);
        // output_integer_graph(uidx, iug, sb, 0);

        ulopt->max_tip_hifi <<= 1;
    }
    ulopt->max_tip_hifi = max_tip_hifi0;

    // output_integer_graph(uidx, iug, "ig_h1", 0);

    u2g_threading(uidx, ulopt, 3, is_bridg, &bu, &uu);


    // fill_u2g(uidx, &bu, &uu);

    // while (cnt) {
        // for (i = cnt = 0, mm_tip = ulopt->max_tip, drop = ulopt->min_ovlp_drop_ratio; i < ulopt->clean_round; i++, drop += step) {
        //     if(drop > ulopt->max_ovlp_drop_ratio) drop = ulopt->max_ovlp_drop_ratio;
            // cnt += ulg_arc_cut_occ(uidx, iug, mm_tip, ulopt->max_tip_hifi, ulopt->is_trio, 2, &bu, &uu);
            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_length(uidx, iug, mm_tip, ulopt->max_tip_hifi, drop/**MIN(drop, ulopt->hom_check_drop_rate)**/, ulopt->is_trio, 2, 1, NULL, &bu, &uu);
            // cnt += ulg_arc_cut_tips(uidx, iug, mm_tip, ulopt->max_tip_hifi, &bu, &uu);

            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_bridge(uidx, iug, mm_tip, ulopt->max_tip_hifi, 0.5, ulopt->is_trio, 2, NULL, &bu, &uu);

            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_misjoin(uidx, iug, mm_tip, ulopt->max_tip_hifi, 0.5, ulopt->is_trio, 2, NULL, &bu, &uu);
        // }

        // for (i = cnt = 0, mm_tip = ((int64_t)0x7fffffff), drop = ulopt->min_ovlp_drop_ratio; i < ulopt->clean_round; i++, drop += step) {
        //     if(drop > ulopt->max_ovlp_drop_ratio) drop = ulopt->max_ovlp_drop_ratio;
            // cnt += ulg_arc_cut_occ(uidx, iug, mm_tip, ulopt->max_tip_hifi, ulopt->is_trio, 2, &bu, &uu);
            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_length(uidx, iug, mm_tip, ulopt->max_tip_hifi, drop/**MIN(drop, ulopt->hom_check_drop_rate)**/, ulopt->is_trio, 2, 1, NULL, &bu, &uu);
            // cnt += ulg_arc_cut_tips(uidx, iug, mm_tip, ulopt->max_tip_hifi, &bu, &uu);

            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_bridge(uidx, iug, mm_tip, ulopt->max_tip_hifi, 0.5, ulopt->is_trio, 2, NULL, &bu, &uu);

            // asg_arc_identify_simple_bubbles_multi(iug->g, ulopt->b_mask_t, 0);
            // cnt += ulg_arc_cut_misjoin(uidx, iug, mm_tip, ulopt->max_tip_hifi, 0.5, ulopt->is_trio, 2, NULL, &bu, &uu);
        // }
    // }

    free(bu.a); free(uu.a); 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
addq $0x1f0, %rax            # imm = 0x1F0
movq %rax, -0x28(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x2100
leaq -0x58(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x2100
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x78(%rbp)
movq $0x1, -0x80(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x1, 0x28(%rax)
jne 0x370b2d
movq -0x10(%rbp), %rax
movsd 0x50(%rax), %xmm0
movsd %xmm0, -0xa8(%rbp)
jmp 0x370b5c
movq -0x10(%rbp), %rax
movsd 0x50(%rax), %xmm0
movq -0x10(%rbp), %rax
subsd 0x48(%rax), %xmm0
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
subq $0x1, %rax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x10(%rbp), %rax
movsd 0x48(%rax), %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
shll %eax
movslq %eax, %rdi
movl $0x1, %esi
callq 0x2140
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x30(%rax)
movq $0x0, -0x90(%rbp)
cmpq $0x2, -0x90(%rbp)
jae 0x370fed
movq $0x0, -0x70(%rbp)
movq -0x10(%rbp), %rax
movsd 0x48(%rax), %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x70(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jge 0x370f22
movsd -0xa0(%rbp), %xmm0
movq -0x10(%rbp), %rax
ucomisd 0x50(%rax), %xmm0
jbe 0x370c13
movq -0x10(%rbp), %rax
movsd 0x50(%rax), %xmm0
movsd %xmm0, -0xa0(%rbp)
movq $0x1, -0x80(%rbp)
movq $0x2, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x80(%rbp)
je 0x370d0c
movq $0x0, -0x80(%rbp)
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
xorl %edx, %edx
callq 0xd8550
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movsd -0xa0(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq -0x10(%rbp), %rax
movl 0x68(%rax), %r8d
movq -0x88(%rbp), %rax
movl %eax, %r9d
movl -0x14(%rbp), %r11d
xorl %eax, %eax
leaq -0x40(%rbp), %r10
leaq -0x58(%rbp), %rax
movl $0x1, (%rsp)
movq $0x0, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x349070
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movl $0x1, %r8d
leaq -0x40(%rbp), %r9
leaq -0x58(%rbp), %rax
movq %rax, (%rsp)
callq 0x342470
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x370c32
movq $0x1, -0x80(%rbp)
movq $0x1, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x80(%rbp)
je 0x370e05
movq $0x0, -0x80(%rbp)
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
xorl %edx, %edx
callq 0xd8550
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movsd -0xa0(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq -0x10(%rbp), %rax
movl 0x68(%rax), %r8d
movq -0x88(%rbp), %rax
movl %eax, %r9d
movl -0x14(%rbp), %r11d
xorl %eax, %eax
leaq -0x40(%rbp), %r10
leaq -0x58(%rbp), %rax
movl $0x1, (%rsp)
movq $0x0, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x349070
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movl $0x1, %r8d
leaq -0x40(%rbp), %r9
leaq -0x58(%rbp), %rax
movq %rax, (%rsp)
callq 0x342470
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x370d2b
movq $0x1, -0x80(%rbp)
movq $0x1, -0x88(%rbp)
movq $0x7fffffff, -0x78(%rbp) # imm = 0x7FFFFFFF
cmpq $0x0, -0x80(%rbp)
je 0x370ef7
movq $0x0, -0x80(%rbp)
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
xorl %edx, %edx
callq 0xd8550
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movsd -0xa0(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq -0x10(%rbp), %rax
movl 0x68(%rax), %r8d
movq -0x88(%rbp), %rax
movl %eax, %r9d
movl -0x14(%rbp), %r11d
xorl %eax, %eax
leaq -0x40(%rbp), %r10
leaq -0x58(%rbp), %rax
movl $0x1, (%rsp)
movq $0x0, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x349070
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x78(%rbp), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
xorl %r8d, %r8d
leaq -0x40(%rbp), %r9
leaq -0x58(%rbp), %rax
movq %rax, (%rsp)
callq 0x342470
movl %eax, %eax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x370e20
jmp 0x370ef9
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
movsd -0x98(%rbp), %xmm0
addsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
jmp 0x370bdd
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %r8d
xorl %eax, %eax
movl %eax, %edx
movl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl $0x1, %r9d
leaq -0x40(%rbp), %r10
leaq -0x58(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x34ae90
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl 0x68(%rax), %r9d
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movss 0x2512b(%rip), %xmm0    # 0x3960ac
movss 0x15917(%rip), %xmm1    # 0x3868a0
movl $0x64, %r8d
movss 0xe0f1(%rip), %xmm2     # 0x37f088
xorl %eax, %eax
leaq -0x40(%rbp), %r10
leaq -0x58(%rbp), %rax
movl $0x1, (%rsp)
movq $0x0, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x34c2d0
cmpl $0x0, %eax
je 0x370fc7
jmp 0x370f5a
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rcx
shlq %rcx
movq %rcx, 0x60(%rax)
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x370bb6
movq -0x60(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movl $0x3, %edx
leaq -0x40(%rbp), %r8
leaq -0x58(%rbp), %r9
callq 0x36efa0
movq -0x30(%rbp), %rdi
callq 0x2210
movq -0x48(%rbp), %rdi
callq 0x2210
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)