// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rcx, 0xa0(%rsp)
movl %edx, 0x38(%rsp)
movq %rdi, %r15
xorpd %xmm0, %xmm0
movapd %xmm0, 0x80(%rsp)
xorl %eax, %eax
movq %rax, 0x90(%rsp)
movq %rax, 0x70(%rsp)
movapd %xmm0, 0x60(%rsp)
movq 0x230(%rdi), %rcx
movq 0x28(%rsi), %rax
movsd 0x50(%rsi), %xmm1
cmpq $0x1, %rax
je 0x227bbd
subsd 0x48(%rsi), %xmm1
decq %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd %xmm0, %xmm1
movsd %xmm1, 0x50(%rsp)
movq 0x60(%rsi), %rbp
movq %rcx, 0x58(%rsp)
movq 0x18(%rcx), %rbx
movq %rsi, %r14
movl 0x14(%rbx), %edi
addl %edi, %edi
movl $0x1, %esi
callq 0x2120
movq %r14, %rsi
movq %rax, 0x30(%rbx)
movb $0x1, %r13b
leaq 0x60(%rsp), %rbx
leaq 0x80(%rsp), %r14
movq %rbp, 0x98(%rsp)
movq %rbp, %r8
movq %r15, 0x40(%rsp)
cmpq $0x0, 0x28(%rsi)
jle 0x227e2f
movl %r13d, 0x4c(%rsp)
movsd 0x48(%rsi), %xmm0
xorl %eax, %eax
movq %rax, 0xb0(%rsp)
movsd 0x50(%rsi), %xmm1
minsd %xmm0, %xmm1
movl 0x58(%rsi), %eax
movl %eax, 0x30(%rsp)
movsd %xmm1, 0xa8(%rsp)
xorps %xmm0, %xmm0
cvtsd2ss %xmm1, %xmm0
movss %xmm0, 0x3c(%rsp)
leaq 0x80(%rsp), %r14
movq %rsi, %r12
movq 0x58(%rsp), %r15
movq 0x18(%r15), %rdi
movq 0x20(%r12), %rsi
xorl %edx, %edx
callq 0xa7e08
movl 0x60(%r12), %ecx
leaq 0x60(%rsp), %rax
movq %r14, %r13
movq %rax, %r14
movq %rax, 0x20(%rsp)
movq %r13, 0x18(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x40(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movl 0x30(%rsp), %ebp
movl %ebp, %edx
movss 0x3c(%rsp), %xmm0
movl $0x2, %r9d
callq 0x2108a9
movl %eax, 0x34(%rsp)
movl 0x60(%r12), %ecx
movq %r14, (%rsp)
movq %r13, %r14
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl $0x1, %r8d
movq %r13, %r9
callq 0x20bff2
orl 0x34(%rsp), %eax
jne 0x227c5e
movl 0x58(%r12), %eax
movl %eax, 0x30(%rsp)
movq 0x18(%r15), %rdi
movq 0x20(%r12), %rsi
xorl %edx, %edx
callq 0xa7e08
movl 0x60(%r12), %ecx
leaq 0x60(%rsp), %r14
movq %r14, 0x20(%rsp)
movq %r13, 0x18(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x40(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movl 0x30(%rsp), %ebp
movl %ebp, %edx
movss 0x3c(%rsp), %xmm0
movl $0x1, %r9d
callq 0x2108a9
movl %eax, 0x34(%rsp)
movl 0x60(%r12), %ecx
movq %r14, (%rsp)
movq %r13, %r14
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl $0x1, %r8d
movq %r13, %r9
callq 0x20bff2
orl 0x34(%rsp), %eax
jne 0x227cf2
leaq 0x60(%rsp), %r13
movq 0x40(%rsp), %rbp
movq 0x18(%r15), %rdi
movq 0x20(%r12), %rsi
xorl %edx, %edx
callq 0xa7e08
movl 0x60(%r12), %ecx
movq %r13, 0x20(%rsp)
movq %r14, 0x18(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq %rbp, %rdi
movq %r15, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movss 0x3c(%rsp), %xmm0
movl $0x1, %r9d
callq 0x2108a9
movl %eax, %ebx
movl 0x60(%r12), %ecx
movq %r13, (%rsp)
movq %rbp, %rdi
movq %r15, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
xorl %r8d, %r8d
movq %r14, %r9
callq 0x20bff2
orl %ebx, %eax
jne 0x227d81
movq 0xb0(%rsp), %rax
incq %rax
movsd 0xa8(%rsp), %xmm0
addsd 0x50(%rsp), %xmm0
cmpq 0x28(%r12), %rax
movq %r12, %rsi
jl 0x227c20
movq %rbp, %r15
movq %r13, %rbx
movq 0x60(%rsi), %r8
movl 0x4c(%rsp), %r13d
leaq 0x80(%rsp), %r14
movq %rbx, 0x8(%rsp)
movq %r14, (%rsp)
movq %rsi, %r12
movq %r15, %rdi
movq %r15, %rbp
movq 0x58(%rsp), %r15
movq %r15, %rsi
xorl %edx, %edx
movl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl $0x1, %r9d
callq 0x211e37
movl 0x60(%r12), %ecx
movq %rbx, 0x18(%rsp)
movq %r14, 0x10(%rsp)
movl $0x1, (%rsp)
movq %rbp, %rdi
movq %r15, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movss 0x1d664(%rip), %xmm0    # 0x2454e8
movss 0xdf2c(%rip), %xmm1     # 0x235db8
movl $0x64, %r8d
movss 0xdf2a(%rip), %xmm2     # 0x235dc4
callq 0x2129bd
testl %eax, %eax
jne 0x227e5b
movq 0x60(%r12), %r8
addq %r8, %r8
movq %r8, 0x60(%r12)
testb $0x1, %r13b
movl $0x0, %r13d
movq %r12, %rsi
movq %rbp, %r15
jne 0x227c09
movq 0x98(%rsp), %rax
movq %rax, 0x60(%rsi)
leaq 0x80(%rsp), %rbx
leaq 0x60(%rsp), %r12
movl $0x3, %edx
movq %r15, %rdi
movq 0xa0(%rsp), %rcx
movq %rbx, %r8
movq %r12, %r9
callq 0x226cc8
movq 0x10(%rbx), %rdi
callq 0x2220
movq 0x10(%r12), %rdi
callq 0x2220
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq