// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/hic.cpp
// Function: hic_short_align(enzyme const*, enzyme const*, ha_ug_index*, ug_opt_t*, kvec_pe_hit**)
int hic_short_align(const enzyme *fn1, const enzyme *fn2, ha_ug_index* idx, ug_opt_t *opt, kvec_pe_hit **rhits)
{
    double index_time = yak_realtime();
    sldat_t sl;
    sl.idx = idx;
    sl.t_ch = idx->t_ch;
    sl.chunk_size = 20000000;
    sl.n_thread = asm_opt.thread_num;
    sl.total_base = sl.total_pair = 0;
    idx->hap_cnt = asm_opt.hap_occ;
    kv_init(sl.hits.a); kv_init(sl.hits.idx); kv_init(sl.hits.occ);


    if(!load_hc_hits(&sl.hits, idx->ug, asm_opt.output_file_name))
    {
        alignment_worker_pipeline(&sl, fn1, fn2);
        write_hc_hits(&sl.hits, idx->ug, asm_opt.output_file_name);
    }
    sl.hits.uID_bits = idx->uID_bits; sl.hits.pos_mode = idx->pos_mode;

    /***debug***/
    if(sl.hits.idx.n == 0) idx_hc_links(&(sl.hits), idx, NULL);
    // optimize_u_trans(&(idx->t_ch->k_trans), &sl.hits, idx);
    // filter_kv_u_trans_t(&(idx->t_ch->k_trans), idx->ug, 0.5);
    /***debug***/
    
    // print_kv_u_trans_t(&(idx->t_ch->k_trans), idx->ug);
    // flter_by_cov(idx, &sl.hits, 2);
    // update_hits(idx, &sl.hits, idx->t_ch->is_r_het);
    ///debug_hc_hits_v14(&sl.hits, asm_opt.output_file_name, sl.idx);
    ////dedup_hits(&(sl.hits), sl.idx);   
    ///write_hc_hits_v14(&sl.hits, asm_opt.output_file_name);
    
    if(asm_opt.misjoin_len > 0/** && (!(asm_opt.ar))**/)//disable it for the UL assembly
    {
        update_switch_unitig(idx->ug, idx->read_g, &(sl.hits), &(idx->t_ch->k_trans), 10, 20, asm_opt.misjoin_len, 0.15);
        renew_idx_para(idx, idx->ug);
    }
    // print_hits_simp(idx, &sl.hits);
    // print_kv_u_trans_t(&(idx->t_ch->k_trans));

    hc_links link;
    init_hc_links(&link, idx->ug->g->n_seq, idx->t_ch);
    ///H_partition hap;
    bubble_type bub; 
    kv_u_trans_t k_trans; 
    kv_init(k_trans); kv_init(k_trans.idx);
    ps_t *s = NULL;
    mb_nodes_t u; 
    kv_init(u.bid); kv_init(u.idx); kv_init(u.u);
    memset(&bub, 0, sizeof(bubble_type));
    bub.round_id = 0; bub.n_round = asm_opt.n_weight;

    resolve_tangles_hic(idx, &bub, &sl.hits, &k_trans);
    measure_distance(idx, idx->ug, &sl.hits, &link, &bub, &(idx->t_ch->k_trans));
    // if((asm_opt.flag & HA_F_VERBOSE_GFA) && load_ps_t(&s, asm_opt.output_file_name))
    // {
    //     bub.round_id = bub.n_round;
    //     label_unitigs_sm(s->s, NULL, idx->ug);
    //     goto skip_flipping;
    // }
    // print_debug_gfa(idx->read_g, idx->ug, opt->coverage_cut, "hic.phasing", opt->sources, opt->ruIndex, 
    // opt->max_hang, opt->min_ovlp, 0, 0, 0);
    
    s = init_ps_t(11, idx->ug->g->n_seq);
    // debug_round_test(s, 11, &bub, &k_trans, &link, &sl, idx, 1000, 10000);
    for (bub.round_id = 0; bub.round_id < bub.n_round; bub.round_id++)
    {
        // identify_bubbles(idx->ug, &bub, idx->t_ch->is_r_het, &(idx->t_ch->k_trans));
        renew_kv_u_trans(&k_trans, &link, &sl.hits, &(idx->t_ch->k_trans), idx, &bub, s->s, NULL, 0);
        // if(bub.round_id == 0) init_phase(idx, &k_trans, &bub, s); 
        // update_trans_g(idx, &k_trans, &bub);
        /*******************************for debug************************************/
        mc_solve(NULL, NULL, &k_trans, idx->ug, idx->read_g, 0.8, R_INF.trio_flag, 
        (bub.round_id == 0? 1 : 0), s->s, 1, &bub, 
        &(idx->t_ch->k_trans), 0, /**(((bub.round_id+1) == bub.n_round)?1:0)**/0);
        // mc_solve(NULL, NULL, &k_trans, idx->ug, idx->read_g, 0.8, R_INF.trio_flag, 
        // (bub.round_id == 0? 1 : 0), s->s, 1, NULL, &(idx->t_ch->k_trans), 0, 0);
        /**
        if((bub.round_id+1) == bub.n_round) {
            prt_debug_hic(asm_opt.output_file_name, idx->ug, idx, opt, &sl.hits, 
            &(idx->t_ch->k_trans), &k_trans, &link, s->s, &(bub));
        }
        **/
        /*******************************for debug************************************/
        label_unitigs_sm(s->s, NULL, idx->ug);

        /*******************************for debug************************************/
        // if(bub.round_id == bub.n_round - 1)
        // {
        //     debug_output_disconnected_hits(idx, &k_trans, &sl.hits, &link, &bub, s->s);
        // }
        /*******************************for debug************************************/
        /**
        init_hic_advance((ha_ug_index*)sl.idx, &sl.hits, &link, &bub, &hap, 0);
        reset_H_partition(&hap, (bub.round_id == 0? 1 : 0));
        init_contig_partition(&hap, idx, &bub, &link);
        phasing_improvement(&hap, &(hap.g_p), idx, &bub, &link);
        label_unitigs(&(hap.g_p), idx->ug);
        **/
    }
    // write_ps_t(s, asm_opt.output_file_name);
    // skip_flipping:
    verbose_het_stat(&bub);

    if(rhits) (*rhits) = get_r_hits_order(&sl.hits, idx->uID_bits, idx->pos_mode, idx->read_g, idx->ug, &bub);

    // tag_reads(idx, &sl.hits, &bub, s->s, opt->sources);

    // print_kv_weight(&k_trans, s->s);

    // horder_t *ho = init_horder_t(&sl.hits, idx->uID_bits, idx->pos_mode, idx->read_g, idx->ug, &bub, &(idx->t_ch->k_trans), opt, 3);

    // print_hc_links(&link, 0, &hap);
    // print_hits_simp(idx, &sl.hits);
    // print_kv_u_trans_t(&(idx->t_ch->k_trans));
    // print_kv_u_trans(&k_trans, &link, s->s);
    // print_bubbles(idx->ug, &bub, sl.hits.a.n?&sl.hits:NULL, NULL/**idx->link**/, idx);
    // print_hits(idx, &sl.hits, fn1, fn2);
    // print_debug_bubble_graph(&bub, idx->ug, asm_opt.output_file_name);
    // print_bubble_chain(&bub);

    // destory_contig_partition(&hap);
    // destory_horder_t(&ho);
    kv_destroy(sl.hits.a); kv_destroy(sl.hits.idx); kv_destroy(sl.hits.occ);
    destory_hc_links(&link);
    kv_destroy(k_trans); kv_destroy(k_trans.idx);
    destory_ps_t(&s);
    kv_destroy(u.bid); kv_destroy(u.idx); kv_destroy(u.u);
    destory_bubbles(&bub);
    return 1;
    

    print_bubbles(idx->ug, &bub, sl.hits.a.n?&sl.hits:NULL, &link, idx);
    collect_hc_reverse_links(&link, idx->ug, &bub);
    normalize_hc_links(&link);
    min_cut_t* cut = clean_hap(&link, &bub, idx->ug);
    ///print_bubbles(idx->ug, &bub, NULL, &link, idx);
    G_partition* gp = clean_bubbles(&link, &bub, cut, idx->ug);
    ///print_hc_links(&link);
    destory_min_cut_t(cut); free(cut);
    destory_G_partition(gp); free(gp);
    destory_bubbles(&bub);
    
    fprintf(stderr, "[M::%s::%.3f] processed %lu pairs; %lu bases\n", __func__, yak_realtime()-index_time, sl.total_pair, sl.total_base);
    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
movq %r8, 0x8(%rsp)
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r12
callq 0x1365ef
leaq 0x78(%rsp), %r13
movq %r14, -0x38(%r13)
movq 0x10(%r14), %rax
movq %rax, 0x58(%r13)
movq $0x1312d00, -0x20(%r13) # imm = 0x1312D00
leaq 0x27a407(%rip), %r15    # 0x295758
movslq 0x7c(%r15), %rax
movq %rax, -0x18(%r13)
xorps %xmm0, %xmm0
movups %xmm0, -0x10(%r13)
movslq 0x1b8(%r15), %rax
movq %rax, 0x48(%r14)
movups %xmm0, 0x30(%r13)
movups %xmm0, 0x20(%r13)
andq $0x0, 0x40(%r13)
movups %xmm0, 0x10(%r13)
movups %xmm0, (%r13)
movq (%r14), %rsi
movq 0x10(%r15), %rdx
movq %r13, %rdi
callq 0x146d08
testl %eax, %eax
jne 0x1b3b7
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x15d602
movq (%r14), %rsi
movq 0x10(%r15), %rdx
movq %r13, %rdi
callq 0x1461bb
movq 0x18(%r14), %rax
movq %rax, 0xc0(%rsp)
movq 0x30(%r14), %rax
movq %rax, 0xc8(%rsp)
cmpq $0x0, 0x90(%rsp)
jne 0x1b3e7
movq %r13, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x14547c
movq 0x1e8(%r15), %rax
movq (%r14), %rdi
testq %rax, %rax
je 0x1b485
movq 0x8(%r14), %rsi
movl $0x138, %ecx            # imm = 0x138
addq 0x10(%r14), %rcx
subq $0x8, %rsp
pushq $0xa
popq %r8
pushq $0x14
popq %r9
movsd 0x21619d(%rip), %xmm0   # 0x2315b8
movq %r13, %rdx
pushq %rax
callq 0x17a187
popq %rax
popq %rcx
movq (%r14), %rdi
movq (%rdi), %rsi
pushq $0x1
popq %rax
pushq $0x40
popq %rdx
pushq $0x1
popq %r8
movl %r8d, %r9d
movl %eax, %ecx
shll %cl, %r9d
movslq %r9d, %rcx
incq %rax
decq %rdx
cmpq %rcx, %rsi
ja 0x1b436
leaq -0x1(%rax), %rcx
movq %rcx, 0x18(%r14)
leaq -0x1(%rdx), %rcx
movq %rcx, 0x28(%r14)
pushq $-0x1
popq %rsi
movq %rsi, %r8
movl %edx, %ecx
shlq %cl, %r8
shrq %r8
movl %eax, %ecx
shrq %cl, %rsi
movq %r8, 0x20(%r14)
movq %rsi, 0x30(%r14)
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
movq %rax, 0x38(%r14)
movq 0x18(%rdi), %rax
movl 0x14(%rax), %esi
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andq %rax, %rsi
movq 0x10(%r14), %rdx
leaq 0xd8(%rsp), %rbx
movq %rbx, %rdi
callq 0xbf70f
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %r12
movaps %xmm0, 0x20(%r12)
movaps %xmm0, 0x10(%r12)
movaps %xmm0, (%r12)
leaq 0x108(%rsp), %r13
movl $0x110, %edx            # imm = 0x110
movq %r13, %rdi
xorl %esi, %esi
callq 0x20e0
movl 0x1e0(%r15), %eax
movl %eax, 0xc(%r13)
movq %r14, %rdi
movq %r13, %rsi
leaq 0x78(%rsp), %rbp
movq %rbp, %rdx
movq %r12, %rcx
callq 0x1601b1
movq (%r14), %rsi
movl $0x138, %r15d           # imm = 0x138
movq 0x10(%r14), %r9
addq %r15, %r9
movq %rbp, %rdx
movq %rbx, %rcx
movq %r13, %r8
callq 0x1456f7
movq (%r14), %rax
movq 0x18(%rax), %rax
movl 0x14(%rax), %edi
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andq %rax, %rdi
pushq $0x1
popq %rsi
callq 0x2120
andl $0x0, 0x8(%r13)
movq %rax, %r12
cmpl $0x0, 0xc(%r13)
je 0x1b5f5
leaq 0x10(%rsp), %rbp
leaq 0x27ace0(%rip), %rbx    # 0x296230
movq 0x10(%r14), %rcx
addq %r15, %rcx
subq $0x8, %rsp
movq %rbp, %rdi
leaq 0xe0(%rsp), %rsi
leaq 0x80(%rsp), %rdx
movq %r14, %r8
movq %r13, %r9
pushq $0x0
pushq $0x0
pushq %r12
callq 0x1a338
addq $0x20, %rsp
movq (%r14), %rcx
movq 0x8(%r14), %r8
xorl %eax, %eax
cmpl $0x0, 0x110(%rsp)
movq 0x28(%rbx), %r9
sete %al
movq 0x10(%r14), %r10
addq %r15, %r10
subq $0x8, %rsp
xorl %edi, %edi
xorl %esi, %esi
movq %rbp, %rdx
movsd 0x215ffb(%rip), %xmm0   # 0x2315b0
pushq $0x0
pushq $0x0
pushq %r10
pushq %r13
pushq $0x1
pushq %r12
pushq %rax
callq 0x1e07b
addq $0x40, %rsp
movq (%r14), %rdx
movq %r12, %rdi
xorl %esi, %esi
callq 0x15c5b0
movl 0x110(%rsp), %eax
incl %eax
movl %eax, 0x110(%rsp)
cmpl 0x114(%rsp), %eax
jb 0x1b550
leaq 0x108(%rsp), %rdi
callq 0x1a4d4
movq 0x8(%rsp), %rbx
testq %rbx, %rbx
je 0x1b630
movq 0x18(%r14), %rsi
movq 0x30(%r14), %rdx
movq (%r14), %r8
movq 0x8(%r14), %rcx
leaq 0x108(%rsp), %r9
leaq 0x78(%rsp), %rdi
callq 0x17f548
movq %rax, (%rbx)
movq 0x88(%rsp), %rdi
callq 0x2220
movq 0xa0(%rsp), %rdi
callq 0x2220
movq 0xb8(%rsp), %rdi
callq 0x2220
leaq 0xd8(%rsp), %rdi
callq 0xbf835
movq 0x20(%rsp), %rdi
callq 0x2220
movq 0x38(%rsp), %rdi
callq 0x2220
movq %r12, %rdi
callq 0x2220
leaq 0x108(%rsp), %rdi
callq 0x13dea7
pushq $0x1
popq %rax
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq