// File: /workspace/github_cpp_makefile_star2_O2/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, 0x98(%rsp)
movl %edx, 0x28(%rsp)
movq %rsi, %r14
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
andq $0x0, 0x80(%rsp)
movaps %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
movq %rdi, 0x30(%rsp)
movq 0x230(%rdi), %r12
movq 0x28(%rsi), %rax
movsd 0x50(%rsi), %xmm0
cmpq $0x1, %rax
jne 0x1d855b
movsd %xmm0, 0x40(%rsp)
jmp 0x1d8577
subsd 0x48(%r14), %xmm0
decq %rax
movapd %xmm0, %xmm1
cvtsi2sd %rax, %xmm0
divsd %xmm0, %xmm1
movsd %xmm1, 0x40(%rsp)
movq 0x60(%r14), %rax
movq %rax, 0x90(%rsp)
movq 0x18(%r12), %rbx
movl 0x14(%rbx), %edi
addl %edi, %edi
pushq $0x1
popq %rsi
callq 0x2120
movq %rax, 0x30(%rbx)
xorl %eax, %eax
leaq 0x50(%rsp), %r15
pushq $0x64
popq %r13
movq %r14, 0x48(%rsp)
cmpq $0x2, %rax
je 0x1d885f
movq %rax, 0xa0(%rsp)
movsd 0x48(%r14), %xmm0
xorl %eax, %eax
cmpq 0x28(%r14), %rax
jge 0x1d87d6
movq %rax, 0xb0(%rsp)
movsd 0x50(%r14), %xmm1
minsd %xmm0, %xmm1
movl 0x58(%r14), %r13d
movsd %xmm1, 0xa8(%rsp)
cvtsd2ss %xmm1, %xmm0
movss %xmm0, 0x2c(%rsp)
pushq $0x1
popq %rax
testq %rax, %rax
je 0x1d8684
movq 0x18(%r12), %rdi
movq 0x20(%r14), %rsi
xorl %edx, %edx
callq 0x6ef72
movl 0x60(%r14), %ecx
movq %r15, 0x20(%rsp)
leaq 0x70(%rsp), %rbx
movq %rbx, 0x18(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x30(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
movl %r13d, %edx
movss 0x2c(%rsp), %xmm0
pushq $0x2
popq %r9
callq 0x1c3596
movl %eax, %ebp
movl 0x60(%r14), %ecx
leaq 0x50(%rsp), %rax
movq %rax, (%rsp)
movq %r15, %rdi
movq %r12, %rsi
movl %r13d, %edx
pushq $0x1
popq %r8
movq %rbx, %r9
callq 0x1bf85b
movl %eax, %eax
addq %rbp, %rax
leaq 0x50(%rsp), %r15
jmp 0x1d85f9
movl 0x58(%r14), %eax
movl %eax, 0x3c(%rsp)
pushq $0x1
popq %rax
testq %rax, %rax
je 0x1d872d
movq 0x18(%r12), %rdi
movq %r12, %rbp
movq 0x48(%rsp), %r12
movq 0x20(%r12), %rsi
xorl %edx, %edx
callq 0x6ef72
movl 0x60(%r12), %ecx
movq %r15, 0x20(%rsp)
leaq 0x70(%rsp), %r13
movq %r13, 0x18(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x30(%rsp), %r15
movq %r15, %rdi
movq %rbp, %rsi
movl 0x3c(%rsp), %r14d
movl %r14d, %edx
movss 0x2c(%rsp), %xmm0
pushq $0x1
popq %r9
callq 0x1c3596
movl %eax, %ebx
movl 0x60(%r12), %ecx
movq %rbp, %r12
leaq 0x50(%rsp), %rax
movq %rax, (%rsp)
movq %r15, %rdi
movq %rbp, %rsi
movl %r14d, %edx
pushq $0x1
popq %r8
movq %r13, %r9
callq 0x1bf85b
movl %eax, %eax
addq %rbx, %rax
leaq 0x50(%rsp), %r15
jmp 0x1d868f
pushq $0x1
popq %rax
movq 0x48(%rsp), %r14
testq %rax, %rax
je 0x1d87b3
movq 0x18(%r12), %rdi
movq 0x20(%r14), %rsi
xorl %edx, %edx
callq 0x6ef72
movl 0x60(%r14), %ecx
movq %r15, 0x20(%rsp)
leaq 0x70(%rsp), %rbx
movq %rbx, 0x18(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x30(%rsp), %rbp
movq %rbp, %rdi
movq %r12, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movss 0x2c(%rsp), %xmm0
pushq $0x1
popq %r9
callq 0x1c3596
movl %eax, %r13d
movl 0x60(%r14), %ecx
movq %r15, (%rsp)
movq %rbp, %rdi
movq %r12, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
xorl %r8d, %r8d
movq %rbx, %r9
callq 0x1bf85b
movl %eax, %eax
addq %r13, %rax
jmp 0x1d8735
movq 0xb0(%rsp), %rax
incq %rax
movsd 0xa8(%rsp), %xmm0
addsd 0x40(%rsp), %xmm0
pushq $0x64
popq %r13
jmp 0x1d85c3
movl 0x60(%r14), %r8d
movq %r15, 0x8(%rsp)
leaq 0x70(%rsp), %rax
movq %rax, (%rsp)
movq 0x30(%rsp), %rdi
movq %r12, %rsi
xorl %edx, %edx
movl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
pushq $0x1
popq %r9
callq 0x1c4682
movl 0x60(%r14), %ecx
movq %r15, 0x18(%rsp)
leaq 0x70(%rsp), %rax
movq %rax, 0x10(%rsp)
movl $0x1, (%rsp)
movq 0x30(%rsp), %rdi
movq %r12, %rsi
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movss 0x1eb81(%rip), %xmm0    # 0x1f73b0
movss 0xf481(%rip), %xmm1     # 0x1e7cb8
movl %r13d, %r8d
movss 0xf482(%rip), %xmm2     # 0x1e7cc4
callq 0x1c51a0
testl %eax, %eax
jne 0x1d8800
shlq 0x60(%r14)
movq 0xa0(%rsp), %rax
incq %rax
jmp 0x1d85a9
movq 0x90(%rsp), %rax
movq %rax, 0x60(%r14)
pushq $0x3
popq %rdx
leaq 0x70(%rsp), %rbx
leaq 0x50(%rsp), %r12
movq 0x30(%rsp), %rdi
movq %r14, %rsi
movq 0x98(%rsp), %rcx
movq %rbx, %r8
movq %r12, %r9
callq 0x1d78bf
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