// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/gfa_ut.cpp
// Function: ul_realignment_gfa(ug_opt_t*, asg_t*, long, double, double, long, long, bub_label_t*, unsigned int, char*, ul_renew_t*, char const*, unsigned long, unsigned long, unsigned long)
void ul_realignment_gfa(ug_opt_t *uopt, asg_t *sg, int64_t clean_round, double min_ovlp_drop_ratio, 
double max_ovlp_drop_ratio, int64_t max_tip, int64_t max_ul_tip, bub_label_t *b_mask_t, uint32_t is_trio, char *o_file,
ul_renew_t *ropt, const char *bin_file, uint64_t free_uld, uint64_t is_bridg, uint64_t deep_clean)
{
    uint64_t i, bn = 0, idn = 0; uint32_t *bl = NULL; uint8_t *r_het = NULL; bubble_type *bub = NULL; ulg_opt_t uu;
    for (i = 0; i < sg->n_seq; ++i) {
        if(sg->seq[i].del) continue;
        sg->seq[i].c = PRIMARY_LABLE;
    }
    // fprintf(stderr, "0[M::%s]\n", __func__);
    hic_clean(sg);
    if(deep_clean) {
        // print_debug_gfa(sg, NULL, uopt->coverage_cut, "bclean", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
        deep_graph_clean(uopt, sg, 1, is_trio, asm_opt.max_short_tip, asm_opt.min_drop_rate, 
        MIN(asm_opt.max_drop_rate, 0.7), 0.75, 1, asm_opt.clean_round, 10/**20**/);
        // print_debug_gfa(sg, NULL, uopt->coverage_cut, "aclean", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
    }
    
    // fprintf(stderr, "1[M::%s]\n", __func__);
    ma_ug_t *init_ug = ul_realignment(uopt, sg, 0, bin_file);
    // fprintf(stderr, "2[M::%s]\n", __func__);
    // exit(1);

    // char* gfa_name = NULL; MALLOC(gfa_name, strlen(o_file)+strlen(bin_file)+50);
    // sprintf(gfa_name, "%s.%s", o_file, bin_file);
    // print_debug_gfa(sg, init_ug, uopt->coverage_cut, gfa_name, uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
    // print_debug_gfa(sg, init_ug, uopt->coverage_cut, gfa_name, uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 1);
    // free(gfa_name);
    
    
    filter_sg_by_ug(sg, init_ug, uopt);
    // fprintf(stderr, "-0-[M::%s]\tUL_INF.a[25].rlen::%u\n", __func__, UL_INF.a[25].rlen);
    // print_debug_gfa(sg, init_ug, uopt->coverage_cut, "UL.debug", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
    // print_ul_alignment(init_ug, &UL_INF, 47072, "after-0");
    bub = gen_bubble_chain(sg, init_ug, uopt, &r_het, ((asm_opt.polyploidy>2)?1:0));
    // fprintf(stderr, "4[M::%s]\n", __func__);
    // print_ul_alignment(init_ug, &UL_INF, 47072, "after-1");
    ul_resolve_t *uidx = init_ul_resolve_t(sg, init_ug, bub, &UL_INF, uopt, r_het);
    if(!free_uld) {///backup
        bn = UL_INF.n; idn = UL_INF.nid.n; MALLOC(bl, bn);
        for (i = 0; i < bn; i++) bl[i] = UL_INF.a[i].rlen;
    }
    // fprintf(stderr, "5[M::%s]\n", __func__);
    // print_ul_alignment(init_ug, &UL_INF, 47072, "after-2");
    // exit(1);
    // if(free_uld) {
        // print_raw_uls_seq(uidx, asm_opt.output_file_name);
        // print_raw_uls_aln(uidx, asm_opt.output_file_name);
    // }
    
    ul_re_correct(uidx, asm_opt.integer_correct_round/**3**/); 
    init_ulg_opt_t(&uu, uopt, clean_round, asm_opt.min_path_drop_rate, asm_opt.max_path_drop_rate, min_ovlp_drop_ratio, max_ovlp_drop_ratio, 0.55, max_tip, max_ul_tip, b_mask_t, is_trio);
    // print_debug_gfa(sg, init_ug, uopt->coverage_cut, "UL.debug0", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 1);
    /**ul2ul_idx_t *u2o = **/gen_ul2ul(uidx, uopt, &uu, 0, is_bridg);
    // print_ul_alignment(init_ug, &UL_INF, 47072, "after-3");

    // print_debug_ul("UL.debug", init_ug, sg, uopt->coverage_cut, uopt->sources, uopt->ruIndex, bub, &UL_INF);

    // resolve_dip_bub_chains(uidx);

    // free(r_het); destory_bubbles(bub); free(bub);
    // if(free_uld) {
        // uidx->uovl.hybrid_ug = gen_hybrid_ug(uidx, uidx->uovl.h_usg);
    //     // print_debug_gfa(sg, uidx->uovl.hybrid_ug, uopt->coverage_cut, "hybrid_ug", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 1);
        // print_debug_gfa(sg, uidx->uovl.hybrid_ug, uopt->coverage_cut, "hybrid_ug", uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
    //     // print_debug_gfa(sg, init_ug, uopt->coverage_cut, bin_file, uopt->sources, uopt->ruIndex, uopt->max_hang, uopt->min_ovlp, 0, 0, 0);
    // }
    // if(is_trio) gen_ul_trio_graph(uopt, uidx, o_file);    
    // exit(0);
    // return uidx->uovl.hybrid_ug;

    asg_t *ng = renew_ng(uidx->uovl.h_usg, init_ug, sg, uopt, ropt->cov, ropt->ruIndex, 16, bin_file);
    destory_bubbles(uidx->bub); free(uidx->bub); ma_ug_destroy(init_ug); free(r_het);
    destroy_ul_resolve_t(uidx); 
    if(free_uld) {
        destory_all_ul_t(&UL_INF); memset((&UL_INF), 0, sizeof(UL_INF));
    } else {
        for (i = 0; i < bn; i++) UL_INF.a[i].rlen = bl[i];
        for (i = bn; i < UL_INF.n; i++) {
            free(UL_INF.a[i].N_site.a); free(UL_INF.a[i].r_base.a); 
            free(UL_INF.a[i].bb.a); memset(&(UL_INF.a[i]), 0, sizeof(UL_INF.a[i]));
        }
        UL_INF.n = bn;

        for (i = idn; i < UL_INF.nid.n; i++) {
            free(UL_INF.nid.a[i].a); memset(&(UL_INF.nid.a[i]), 0, sizeof(UL_INF.nid.a[i])); 
        }
        UL_INF.nid.n = idn; free(bl);
    }

    asg_destroy((*(ropt->sg))); (*(ropt->sg)) = ng; 
    (*(ropt->src)) = R_INF.paf; (*(ropt->r_src)) = R_INF.reverse_paf;
    (*(ropt->n_read)) = R_INF.total_reads; (*(ropt->readLen)) = R_INF.read_length;
    renew_R_to_U(ng, (*(ropt->src)), (*(ropt->r_src)), (*(ropt->n_read)), (*(ropt->cov)), ropt->ruIndex, ropt->max_hang, ropt->mini_ovlp);
    post_rescue(uopt, (*(ropt->sg)), (*(ropt->src)), (*(ropt->r_src)), ropt->ruIndex, ropt->b_mask_t, 0, NULL);
    // print_raw_uls_aln(uidx, asm_opt.output_file_name);
    // exit(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %r9, 0x30(%rsp)
movq %r8, (%rsp)
movq %rcx, 0x48(%rsp)
movsd %xmm1, 0x40(%rsp)
movsd %xmm0, 0x38(%rsp)
movq %rdx, 0x28(%rsp)
movq %rsi, %r12
movq %rdi, %r13
movq 0x130(%rsp), %rbx
movq 0x118(%rsp), %r15
movl 0x100(%rsp), %ebp
andq $0x0, 0x50(%rsp)
xorl %eax, %eax
movl 0x14(%r12), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpq %rcx, %rax
jae 0x1dcbef
movq 0x20(%r12), %rcx
cmpl $0x0, (%rcx,%rax,8)
js 0x1dcbea
movb $0x0, 0x4(%rcx,%rax,8)
incq %rax
jmp 0x1dcbca
movq %r12, %rdi
callq 0x84414
testq %rbx, %rbx
je 0x1dcc4c
leaq 0x76b55(%rip), %rax     # 0x253758
cvtss2sd 0x15c(%rax), %xmm0
cvtss2sd 0x160(%rax), %xmm1
movslq 0x11c(%rax), %r8
minsd 0x68ce(%rip), %xmm1     # 0x1e34f0
movslq 0x104(%rax), %rax
movzbl %bpl, %ecx
pushq $0x1
popq %rdx
movsd 0x6950(%rip), %xmm2     # 0x1e3588
pushq $0x1
popq %r9
movq %r13, %rdi
movq %r12, %rsi
pushq $0xa
pushq %rax
callq 0x1dd00f
popq %rax
popq %rcx
xorl %r14d, %r14d
movq %r13, %rdi
movq %r12, %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0x1a18a9
movq %rax, %rbx
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x1ade7c
leaq 0x76ae1(%rip), %rax     # 0x253758
xorl %r8d, %r8d
cmpl $0x3, 0x1bc(%rax)
setge %r8b
leaq 0x50(%rsp), %r15
movq %r12, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x1afe25
movq (%r15), %r9
leaq 0x77673(%rip), %r15     # 0x254318
movq %r12, %rdi
movq %rbx, 0x10(%rsp)
movq %rbx, %rsi
movq %rax, %rdx
movq %r15, %rcx
movq %r13, %r8
movq %r9, 0x20(%rsp)
callq 0x1b26b8
movq %rax, %rbp
movl $0x0, %eax
movq %rax, 0x8(%rsp)
movl $0x0, %ebx
movq 0x120(%rsp), %rax
testq %rax, %rax
jne 0x1dcd26
movq %rbp, 0x18(%rsp)
movq (%r15), %rax
movq %rax, 0x8(%rsp)
movq 0x50(%r15), %rbx
leaq (,%rbx,4), %rdi
callq 0x2280
movq %rax, %r14
movq 0x48(%r15), %rax
addq $0x18, %rax
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x1dcd21
movl (%rax), %edx
movl %edx, (%r14,%rcx,4)
incq %rcx
addq $0x58, %rax
jmp 0x1dcd0d
movq 0x18(%rsp), %rbp
leaq 0x76a2b(%rip), %rax     # 0x253758
movslq 0x258(%rax), %rsi
movq %rbp, %rdi
callq 0x1bdca6
movq 0x18(%r13), %rax
leaq 0x58(%rsp), %rdx
movq %rax, (%rdx)
movss 0x20(%r13), %xmm0
movss %xmm0, 0x8(%rdx)
movq 0x28(%r13), %rax
movq %rax, 0x10(%rdx)
movsd 0x38(%r13), %xmm0
movsd %xmm0, 0x18(%rdx)
movq 0x30(%rsp), %rax
movq %rax, 0x20(%rdx)
movq 0x28(%rsp), %rax
movq %rax, 0x28(%rdx)
leaq 0x769d9(%rip), %rax     # 0x253758
cvtps2pd 0x178(%rax), %xmm0
movups %xmm0, 0x48(%rdx)
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x30(%rdx)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x38(%rdx)
movabsq $0x3fe199999999999a, %rax # imm = 0x3FE199999999999A
movq %rax, 0x40(%rdx)
movq 0x48(%rsp), %rax
movq %rax, 0x58(%rdx)
movq (%rsp), %rax
movq %rax, 0x60(%rdx)
movl 0x100(%rsp), %eax
movl %eax, 0x68(%rdx)
movq %rbp, %rdi
movq %r13, %rsi
xorl %ecx, %ecx
movq 0x128(%rsp), %r8
callq 0x1da1f0
movq 0x240(%rbp), %rdi
movq 0x110(%rsp), %rax
movq 0x28(%rax), %r9
movq 0x30(%rax), %r8
movq 0x10(%rsp), %rsi
movq %r12, %rdx
movq %r13, (%rsp)
movq %r13, %rcx
pushq 0x118(%rsp)
pushq $0x10
callq 0x1d43c9
popq %rcx
popq %rdx
movq %rax, %r12
movq 0x28(%rbp), %rdi
callq 0xf6a60
movq 0x28(%rbp), %rdi
callq 0x2220
movq 0x10(%rsp), %rdi
callq 0x6921d
movq 0x20(%rsp), %rdi
callq 0x2220
movq %rbp, %rdi
callq 0x1dc8be
cmpq $0x0, 0x120(%rsp)
je 0x1dce82
movq %r15, %rdi
callq 0x7d55
xorps %xmm0, %xmm0
movups %xmm0, 0x50(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x20(%r15)
movups %xmm0, 0x10(%r15)
movups %xmm0, (%r15)
andq $0x0, 0x60(%r15)
jmp 0x1dcf4e
movq 0x48(%r15), %rax
addq $0x18, %rax
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x1dcea0
movl (%r14,%rcx,4), %edx
movl %edx, (%rax)
incq %rcx
addq $0x58, %rax
jmp 0x1dce8c
imulq $0x58, %rbx, %r13
movq %rbx, %rbp
cmpq 0x50(%r15), %rbp
jae 0x1dcf0a
movq 0x48(%r15), %rax
movq 0x38(%rax,%r13), %rdi
callq 0x2220
movq 0x48(%r15), %rax
movq 0x10(%rax,%r13), %rdi
callq 0x2220
movq 0x48(%r15), %rax
movq 0x30(%rax,%r13), %rdi
callq 0x2220
movq 0x48(%r15), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x40(%rax,%r13)
movups %xmm0, 0x30(%rax,%r13)
movups %xmm0, 0x20(%rax,%r13)
andq $0x0, 0x50(%rax,%r13)
movups %xmm0, 0x10(%rax,%r13)
movups %xmm0, (%rax,%r13)
incq %rbp
addq $0x58, %r13
jmp 0x1dcea7
movq %rbx, 0x50(%r15)
movq 0x8(%rsp), %rbp
movq %rbp, %rbx
shlq $0x4, %rbx
movq %rbp, %r13
cmpq (%r15), %r13
jae 0x1dcf43
movq 0x10(%r15), %rax
movq (%rax,%rbx), %rdi
callq 0x2220
movq 0x10(%r15), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax,%rbx)
incq %r13
addq $0x10, %rbx
jmp 0x1dcf1d
movq %rbp, (%r15)
movq %r14, %rdi
callq 0x2220
movq 0x110(%rsp), %rbx
movq 0x20(%rbx), %rax
movq (%rax), %rdi
callq 0x68f68
movq 0x20(%rbx), %rax
movq %r12, (%rax)
leaq 0x772c0(%rip), %rax     # 0x254230
movq 0x78(%rax), %rcx
movq (%rbx), %rdx
movq %rcx, (%rdx)
movq 0x80(%rax), %rcx
movq 0x8(%rbx), %rdx
movq %rcx, (%rdx)
movq 0x50(%rax), %rcx
movq 0x10(%rbx), %rdx
movq %rcx, (%rdx)
movq 0x18(%rax), %rax
movq 0x18(%rbx), %rcx
movq %rax, (%rcx)
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq (%rax), %rsi
movq (%rcx), %rdx
movq 0x10(%rbx), %rax
movq (%rax), %rcx
movq 0x30(%rbx), %rax
movq (%rax), %r8
movq 0x28(%rbx), %r9
movl 0x40(%rbx), %eax
movl 0x48(%rbx), %edi
pushq %rdi
pushq %rax
callq 0x1dca5c
popq %rax
popq %rcx
movq 0x20(%rbx), %rax
movq (%rax), %rsi
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
movq (%rax), %rdx
movq (%rcx), %rcx
movq 0x28(%rbx), %r8
movq 0x38(%rbx), %r9
subq $0x10, %rsp
xorps %xmm0, %xmm0
movups %xmm0, (%rsp)
movq 0x10(%rsp), %rdi
callq 0x1ae9ac
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq