// File: /workspace/github_cpp_makefile_star2_O2/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 $0x228, %rsp            # imm = 0x228
movq %r8, 0x8(%rsp)
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %r12
callq 0xefea7
leaq 0x50(%rsp), %r15
movq %r14, -0x38(%r15)
movq 0x10(%r14), %rax
movq %rax, 0x58(%r15)
movq $0x1312d00, -0x20(%r15) # imm = 0x1312D00
leaq 0x1374a9(%rip), %rbx    # 0x253758
movslq 0x7c(%rbx), %rax
movq %rax, -0x18(%r15)
xorps %xmm0, %xmm0
movups %xmm0, -0x10(%r15)
movslq 0x1b8(%rbx), %rax
movq %rax, 0x48(%r14)
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x20(%r15)
andq $0x0, 0x40(%r15)
movups %xmm0, 0x10(%r15)
movups %xmm0, (%r15)
movq (%r14), %rsi
movq 0x10(%rbx), %rdx
movq %r15, %rdi
callq 0xff599
testl %eax, %eax
jne 0x11c314
leaq 0x18(%rsp), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x11718b
movq (%r14), %rsi
movq 0x10(%rbx), %rdx
movq %r15, %rdi
callq 0xfeae5
movq 0x18(%r14), %rax
movq %rax, 0x98(%rsp)
movq 0x30(%r14), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0x68(%rsp)
jne 0x11c341
movq %r15, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0xfdcd5
movq 0x1e8(%rbx), %rax
testq %rax, %rax
je 0x11c387
movq (%r14), %rdi
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 0xc7197(%rip), %xmm0    # 0x1e3508
movq %r15, %rdx
pushq %rax
callq 0x136181
popq %rax
popq %rcx
movq (%r14), %rsi
movq %r14, %rdi
callq 0x11aef4
movq (%r14), %rax
movq 0x10(%r14), %rdx
movq 0x18(%rax), %rax
movl 0x14(%rax), %esi
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andq %rax, %rsi
leaq 0xe8(%rsp), %rbx
movq %rbx, %rdi
callq 0x83ca2
xorps %xmm0, %xmm0
leaq 0xb0(%rsp), %r13
movaps %xmm0, 0x20(%r13)
movaps %xmm0, 0x10(%r13)
movaps %xmm0, (%r13)
leaq 0x118(%rsp), %rbp
xorl %r12d, %r12d
movl $0x110, %edx            # imm = 0x110
movq %rbp, %rdi
xorl %esi, %esi
callq 0x20e0
leaq 0x137370(%rip), %rax    # 0x253758
movl 0x1e0(%rax), %eax
movl %eax, 0xc(%rbp)
movq %r14, %rdi
movq %rbp, %rsi
movq %r15, %rdx
movq %r13, %rcx
callq 0x119c12
movq (%r14), %rsi
movq %r15, %rdx
movl $0x138, %r15d           # imm = 0x138
movq 0x10(%r14), %r9
addq %r15, %r9
movq %rbx, %rcx
movq %rbp, %r8
callq 0xfdf3d
movq (%r14), %rax
movq 0x18(%rax), %rax
movl 0x14(%rax), %esi
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andq %rax, %rsi
pushq $0xb
popq %rdi
callq 0x1193f3
movq %rax, %rbx
movq %rax, 0x10(%rsp)
movl %r12d, 0x120(%rsp)
cmpl 0x124(%rsp), %r12d
jae 0x11c4f3
movq 0x10(%r14), %rcx
addq %r15, %rcx
subq $0x8, %rsp
movq %r13, %rdi
leaq 0xf0(%rsp), %rsi
leaq 0x58(%rsp), %rdx
movq %r14, %r8
movq %rbp, %r9
pushq $0x0
pushq $0x0
pushq (%rbx)
callq 0x1191a6
addq $0x20, %rsp
movq (%r14), %rcx
movq 0x8(%r14), %r8
xorl %eax, %eax
cmpl $0x0, 0x120(%rsp)
leaq 0x137d90(%rip), %rdx    # 0x254230
movq 0x28(%rdx), %r9
sete %al
movq 0x10(%r14), %r10
addq %r15, %r10
subq $0x8, %rsp
xorl %edi, %edi
xorl %esi, %esi
movq %r13, %rdx
movsd 0xc703f(%rip), %xmm0    # 0x1e3500
pushq $0x0
pushq $0x0
pushq %r10
pushq %rbp
pushq $0x1
pushq (%rbx)
pushq %rax
callq 0x12b808
addq $0x40, %rsp
movq (%rbx), %rdi
movq (%r14), %rdx
xorl %esi, %esi
callq 0x116189
movl 0x120(%rsp), %r12d
incl %r12d
jmp 0x11c442
leaq 0x118(%rsp), %rdi
callq 0x1197d6
movq 0x8(%rsp), %rbx
testq %rbx, %rbx
je 0x11c52e
movq 0x18(%r14), %rsi
movq 0x30(%r14), %rdx
movq (%r14), %r8
movq 0x8(%r14), %rcx
leaq 0x118(%rsp), %r9
leaq 0x50(%rsp), %rdi
callq 0x13ca45
movq %rax, (%rbx)
movq 0x60(%rsp), %rdi
callq 0x2220
movq 0x78(%rsp), %rdi
callq 0x2220
movq 0x90(%rsp), %rdi
callq 0x2220
leaq 0xe8(%rsp), %rdi
callq 0x83da5
movq 0xc0(%rsp), %rdi
callq 0x2220
movq 0xd8(%rsp), %rdi
callq 0x2220
leaq 0x10(%rsp), %rdi
callq 0x11943a
leaq 0x118(%rsp), %rdi
callq 0xf6a60
pushq $0x1
popq %rax
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq