// File: 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
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq 0x40(%rbp), %rax
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
movsd %xmm1, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x40(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x14(%rcx), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl %ecx, %ecx
cmpq %rcx, %rax
jae 0x379058
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x48(%rbp), %rcx
movl (%rax,%rcx,8), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
je 0x379039
jmp 0x37904a
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x48(%rbp), %rcx
movb $0x0, 0x4(%rax,%rcx,8)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x379008
movq -0x10(%rbp), %rdi
callq 0xfd5f0
cmpq $0x0, 0x40(%rbp)
je 0x37916c
movq -0x8(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x118(%rbp)
movl 0x10(%rbp), %eax
movb %al, -0x109(%rbp)
leaq 0x4b766(%rip), %rax     # 0x3c47f8
movslq 0x11c(%rax), %rax
movq %rax, -0x108(%rbp)
leaq 0x4b751(%rip), %rax     # 0x3c47f8
movss 0x15c(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x100(%rbp)
leaq 0x4b736(%rip), %rax     # 0x3c47f8
movss 0x160(%rax), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x9152(%rip), %xmm0     # 0x382228
ucomisd %xmm1, %xmm0
jb 0x3790f9
leaq 0x4b715(%rip), %rax     # 0x3c47f8
movss 0x160(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x128(%rbp)
jmp 0x37910b
movsd 0x9127(%rip), %xmm0     # 0x382228
movsd %xmm0, -0x128(%rbp)
jmp 0x37910b
movsd -0x100(%rbp), %xmm0
movq -0x108(%rbp), %r8
movb -0x109(%rbp), %cl
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rdi
movsd -0x128(%rbp), %xmm1
leaq 0x4b6bb(%rip), %rax     # 0x3c47f8
movslq 0x104(%rax), %rax
movl $0x1, %edx
movsd 0x5ecf(%rip), %xmm2     # 0x37f020
movl $0x1, %r9d
movzbl %cl, %ecx
movq %rax, (%rsp)
movq $0xa, 0x8(%rsp)
callq 0x379660
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq 0x28(%rbp), %rcx
xorl %edx, %edx
callq 0x30a0a0
movq %rax, -0xe8(%rbp)
movq -0x10(%rbp), %rdi
movq -0xe8(%rbp), %rsi
movq -0x8(%rbp), %rdx
callq 0x31f740
movq -0x10(%rbp), %rdi
movq -0xe8(%rbp), %rsi
movq -0x8(%rbp), %rdx
leaq 0x4b648(%rip), %rax     # 0x3c47f8
movl 0x1bc(%rax), %r8d
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x2, %r8d
cmovgl %ecx, %eax
leaq -0x68(%rbp), %rcx
movzbl %al, %r8d
callq 0x322770
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movq -0xe8(%rbp), %rsi
movq -0x70(%rbp), %rdx
movq -0x8(%rbp), %r8
movq -0x68(%rbp), %r9
leaq 0x4c1c4(%rip), %rcx     # 0x3c53b8
callq 0x327880
movq %rax, -0xf0(%rbp)
cmpq $0x0, 0x30(%rbp)
jne 0x379278
leaq 0x4c1aa(%rip), %rax     # 0x3c53b8
movq 0x50(%rax), %rax
movq %rax, -0x50(%rbp)
leaq 0x4c19b(%rip), %rax     # 0x3c53b8
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
shlq $0x2, %rdi
callq 0x2270
movq %rax, -0x60(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x50(%rbp), %rax
jae 0x379276
leaq 0x4c16a(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rax
imulq $0x58, -0x48(%rbp), %rcx
addq %rcx, %rax
movl 0x18(%rax), %edx
movq -0x60(%rbp), %rax
movq -0x48(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x37923d
jmp 0x379278
movq -0xf0(%rbp), %rdi
leaq 0x4b572(%rip), %rax     # 0x3c47f8
movslq 0x258(%rax), %rsi
callq 0x33eb80
movq -0x8(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq 0x4b557(%rip), %rax     # 0x3c47f8
movss 0x178(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
leaq 0x4b544(%rip), %rax     # 0x3c47f8
movss 0x17c(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
movsd -0x20(%rbp), %xmm2
movsd -0x28(%rbp), %xmm3
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %r8
movq -0x40(%rbp), %r9
movl 0x10(%rbp), %eax
leaq -0xe0(%rbp), %rdi
movsd 0x8f20(%rip), %xmm4     # 0x382208
movl %eax, (%rsp)
callq 0x375320
movq -0xf0(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq 0x38(%rbp), %r8
leaq -0xe0(%rbp), %rdx
xorl %ecx, %ecx
callq 0x374750
movq -0xf0(%rbp), %rax
movq 0x240(%rax), %rdi
movq -0xe8(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x8(%rbp), %rcx
movq 0x20(%rbp), %rax
movq 0x30(%rax), %r8
movq 0x20(%rbp), %rax
movq 0x28(%rax), %r9
movq 0x28(%rbp), %rax
movq $0x10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x368d80
movq %rax, -0xf8(%rbp)
movq -0xf0(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x1c4a90
movq -0xf0(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x2210
movq -0xe8(%rbp), %rdi
callq 0xcd6f0
movq -0x68(%rbp), %rdi
callq 0x2210
movq -0xf0(%rbp), %rdi
callq 0x378b60
cmpq $0x0, 0x30(%rbp)
je 0x3793c3
leaq 0x4c012(%rip), %rdi     # 0x3c53b8
callq 0xbb90
leaq 0x4c006(%rip), %rdi     # 0x3c53b8
xorl %esi, %esi
movl $0x68, %edx
callq 0x2100
jmp 0x379531
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x50(%rbp), %rax
jae 0x379404
movq -0x60(%rbp), %rax
movq -0x48(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
leaq 0x4bfd1(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rax
imulq $0x58, -0x48(%rbp), %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x3793cb
movq -0x50(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
leaq 0x4bfa1(%rip), %rcx     # 0x3c53b8
cmpq 0x50(%rcx), %rax
jae 0x3794a5
leaq 0x4bf90(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rax
imulq $0x58, -0x48(%rbp), %rcx
addq %rcx, %rax
movq 0x38(%rax), %rdi
callq 0x2210
leaq 0x4bf74(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rax
imulq $0x58, -0x48(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdi
callq 0x2210
leaq 0x4bf58(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rax
imulq $0x58, -0x48(%rbp), %rcx
addq %rcx, %rax
movq 0x30(%rax), %rdi
callq 0x2210
leaq 0x4bf3c(%rip), %rax     # 0x3c53b8
movq 0x48(%rax), %rdi
imulq $0x58, -0x48(%rbp), %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x58, %edx
callq 0x2100
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x37940c
movq -0x50(%rbp), %rcx
leaq 0x4bf08(%rip), %rax     # 0x3c53b8
movq %rcx, 0x50(%rax)
movq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
leaq 0x4bef1(%rip), %rcx     # 0x3c53b8
cmpq (%rcx), %rax
jae 0x37951a
leaq 0x4bee5(%rip), %rax     # 0x3c53b8
movq 0x10(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x2210
leaq 0x4bec7(%rip), %rax     # 0x3c53b8
movq 0x10(%rax), %rdi
movq -0x48(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2100
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x3794bc
movq -0x58(%rbp), %rcx
leaq 0x4be93(%rip), %rax     # 0x3c53b8
movq %rcx, (%rax)
movq -0x60(%rbp), %rdi
callq 0x2210
movq 0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rdi
callq 0xcd170
movq -0xf8(%rbp), %rcx
movq 0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq %rcx, (%rax)
leaq 0x4bd76(%rip), %rax     # 0x3c52d0
movq 0x78(%rax), %rcx
movq 0x20(%rbp), %rax
movq (%rax), %rax
movq %rcx, (%rax)
leaq 0x4bd61(%rip), %rax     # 0x3c52d0
movq 0x80(%rax), %rcx
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
leaq 0x4bd48(%rip), %rax     # 0x3c52d0
movq 0x50(%rax), %rcx
movq 0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq %rcx, (%rax)
leaq 0x4bd32(%rip), %rax     # 0x3c52d0
movq 0x18(%rax), %rcx
movq 0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, (%rax)
movq -0xf8(%rbp), %rdi
movq 0x20(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rsi
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rdx
movq 0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rcx
movq 0x20(%rbp), %rax
movq 0x30(%rax), %rax
movq (%rax), %r8
movq 0x20(%rbp), %rax
movq 0x28(%rax), %r9
movq 0x20(%rbp), %rax
movq 0x40(%rax), %rax
movl %eax, %r10d
movq 0x20(%rbp), %rax
movq 0x48(%rax), %rax
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x378dd0
movq -0x8(%rbp), %rdi
movq 0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rsi
movq 0x20(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rdx
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rcx
movq 0x20(%rbp), %rax
movq 0x28(%rax), %r8
movq 0x20(%rbp), %rax
movq 0x38(%rax), %r9
xorl %eax, %eax
movq $0x0, (%rsp)
movq $0x0, 0x8(%rsp)
callq 0x320d00
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopl (%rax)