// File: chhylp123[P]hifiasm/inter.cpp
// Function: direct_gchain(mg_tbuf_s*, ul_vec_t*, glchain_t*, gdpchain_t*, st_mt_t*, haplotype_evdience_alloc*, ul_idx_t const*, ug_opt_t const*, long, double, long, long, Chain_Data*, asg_t const*, long)
uint32_t direct_gchain(mg_tbuf_t *b, ul_vec_t *rch, glchain_t *ll, gdpchain_t *gdp, st_mt_t *sps, haplotype_evdience_alloc *hap, const ul_idx_t *uref, const ug_opt_t *uopt,
int64_t bw, double diff_ec_ul, int64_t max_skip, int64_t ulid, Chain_Data* dp, const asg_t *rg, int64_t linear_only)
{
	// if(ulid != 86660) return 0;
	kv_ul_ov_t *idx = &(ll->lo), *init = &(ll->tk); int64_t max_idx;
	idx->n = init->n = 0;
	gl_rg2ug_gen(rch, idx, uref, 1, 2, ulid);
	if(idx->n == 0) return 0;
	///generate linear chains
	gen_linear_chains(idx, init, uref, uopt, bw, diff_ec_ul, rch->rlen, dp);
	// gen_linear_chains_backup(idx, init, uref, uopt, bw, diff_ec_ul, rch->rlen, max_skip, ll, sps);
// 	gen_linear_chains_backup(kv_ul_ov_t *res, kv_ul_ov_t *buf, const ul_idx_t *uref, const ug_opt_t *uopt, int64_t bw, 
// double diff_ec_ul, int64_t qlen, int64_t max_skip, glchain_t *bufg, st_mt_t *bufs)
	assert(idx->n);
	if(idx->n == 0) return 0;
	///idx includes unitig alignments, while init keeps read alignments 
	// fprintf(stderr, "\n++[M::%s::%.*s(id:%ld), len:%u] idx->n:%lu\n", __func__, UL_INF.nid.a[ulid].n, UL_INF.nid.a[ulid].a,
	// ulid, rch->rlen, (uint64_t)idx->n);

	dump_linear_chain(uref->ug, idx, &(gdp->l), rch->rlen, ulid);
	if(gdp->l.n == 0) return 0;
	// fprintf(stderr, "\n+++[M::%s::id->%ld, len->%u] idx->n:%lu\n", __func__, ulid, rch->rlen, (uint64_t)idx->n);
	// kv_resize(uint64_t, ll->srt.a, idx->n); kv_resize(uint64_t, hap->snp_srt, idx->n); kv_resize(uint64_t, gdp->v, idx->n);
	// occ = gl_chain_advance(&(gdp->l), &(gdp->swap), uref, uopt, G_CHAIN_BW, diff_ec_ul, qlen, UG_SKIP, dumy->overlapID, ll->srt.a.a, hap->snp_srt.a, G_CHAIN_TRANS_WEIGHT, 0, NULL, uref->ug, debug_i, km);
	// print_ru_raw_chains(idx, init,  &(gdp->l), rch, uref->ug);

	kv_resize(uint64_t, ll->srt.a, gdp->l.n);
	max_idx = gl_chain_graph(b->km, uref, uref->ug, &(gdp->l), &(gdp->swap), &(gdp->dst), &(gdp->out),
        &(gdp->path), rch->rlen, uopt, G_CHAIN_BW, linear_only?-1:diff_ec_ul, N_GCHAIN_RATE, ll->srt.a.a, sps, dp, UG_SKIP_GRAPH_N, UG_ITER_N, UG_DIS_N, 1);
	//sps -> idx; (gdp->l) -> alignments
	if(max_idx >= 0) {
		max_idx = select_max_gchain(b->km, uref, ulid, sps, &(gdp->l), &(ll->tk), uref->ug->g, &(gdp->dst_done), &(gdp->out), &(gdp->path), &(gdp->swap));
		if(max_idx) {
			if((!linear_only) || ((linear_only) && (gdp->swap.a[0].qe-gdp->swap.a[0].qs) 
																		>= (rch->rlen*P_CHAIN_COV))) {
				update_ul_vec_t(uref, idx, init, rch, &(gdp->swap), &(gdp->l), ulid, rg, dp, UG_SKIP_GRAPH_N, UG_ITER_N, UG_DIS_N);
			} 
			return (rch->dd == 1?1:0);
		}
	}
	// if(max_idx >= 0 && select_max_gchain(b->km, uref, ulid, sps, &(gdp->l), &(ll->tk), uref->ug->g, &(gdp->dst_done), &(gdp->out), &(gdp->path), &(gdp->swap))){
	// 	update_ul_vec_t(uref, idx, init, rch, &(gdp->swap), &(gdp->l), ulid, rg, dp, UG_SKIP_GRAPH_N, UG_ITER_N, UG_DIS_N);
	// 	return (rch->dd == 1?1:0);
	// }

	/**
	///buffer
	kv_resize(uint64_t, ll->srt.a, gdp->l.n); kv_resize(uint64_t, hap->snp_srt, gdp->l.n);
	kv_resize(uint64_t, gdp->v, gdp->l.n); kv_resize(int64_t, gdp->f, gdp->l.n);
	max_idx = hc_gchain1_dp(b->km, uref, uref->ug, &(gdp->l), &(gdp->swap), &(gdp->dst), &(gdp->out), &(gdp->path), rch->rlen,
	uopt, bw, diff_ec_ul, N_GCHAIN_RATE, ll->srt.a.a, sps, gdp->f.a, hap->snp_srt.a, gdp->v.a);
	// fprintf(stderr, "++++[M::%s::id->%ld, len->%u] gdp->l.n:%lu\n", __func__, ulid, rch->rlen, (uint64_t)gdp->l.n);
	// fprintf(stderr, "+[M::%s::] gdp->l.n:%lu\n", __func__, (uint64_t)gdp->l.n);
	//sps has the chain idx; gdp->l has the chain
	if(max_idx >= 0 && gen_max_gchain_adv(b->km, uref, ulid, sps, &(gdp->l), idx, init, rch->rlen, P_CHAIN_COV, 0.3, 
			0.1, PRIMARY_UL_CHAIN_MIN, uref->ug->g, &(gdp->dst_done), &(gdp->out), &(gdp->path), ll->srt.a.a, &(gdp->swap))) {
		// update_ul_vec_t(rch, &(gdp->l), uref);
		// fprintf(stderr, "\n++[M::%s::(id:%ld), len:%u]\n", __func__, ulid, rch->rlen);
		update_ul_vec_t(uref, idx, init, rch, &(gdp->swap), &(gdp->l), ulid);
		// __ac_X31_hash_string("hehe");
		// if(rch->dd == 1) {
		// 	fprintf(stderr, "[M::%s::%.*s(id:%ld)] ulen->%u\n", __func__, UL_INF.nid.a[ulid].n, UL_INF.nid.a[ulid].a, ulid, rch->rlen);
		// }
		return (rch->dd == 1?1:0);
	// } else {
	// 	// uint64_t i;
	// 	fprintf(stderr, "unsuccess->[M::%s::id->%ld, len->%u] gdp->l.n:%lu\n", __func__, ulid, rch->rlen, (uint64_t)gdp->l.n);
	// 	for (i = 0; i < gdp->l.n; ++i) {
	// 		fprintf(stderr, "(%lu)\t%u\t%u\t%c\tutg%.6d%c(%u)\t%u\t%u\tsrc:%u\tscore:%d\n", 
	// 			i, gdp->l.a[i].qs, gdp->l.a[i].qe, "+-"[gdp->l.a[i].v&1], (int32_t)(gdp->l.a[i].v>>1)+1, "lc"[uref->ug->u.a[gdp->l.a[i].v>>1].circ], uref->ug->u.a[gdp->l.a[i].v>>1].len,
	// 			gdp->l.a[i].rs, gdp->l.a[i].re, gdp->l.a[i].v^1, gdp->l.a[i].score);
	// 	}
	}
	**/

	

	// occ = gl_chain_advance(idx, ll->tk.a+ll->tk.n, uref, uopt, G_CHAIN_BW, diff_ec_ul, qlen, UG_SKIP, dumy->overlapID, ll->srt.a.a, hap->snp_srt.a, G_CHAIN_TRANS_WEIGHT, 0, NULL, uref->ug, debug_i, km);

	// simple_g_chain_dp(idx, buf->a, uref, uopt, bw, diff_ec_ul, rch->rlen, max_skip, ll->srt.a.a, hap->snp_srt.a, sps->a);
	// if(check_extension_end(idx, rch->rlen, buf->a)) {
	// 	// ug2rg_gen(idx->a[idx->n-1].qs, idx->a[idx->n-1].qe, buf->a + idx->a[idx->n-1].ts, idx->a[idx->n-1].te - idx->a[idx->n-1].ts, rch);
	// } else {///need graph chaining

	// }

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x110, %rsp            # imm = 0x110
movq 0x48(%rbp), %rax
movq 0x40(%rbp), %rax
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x30(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdx, -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movq %r8, -0x50(%rbp)
movq %r9, -0x58(%rbp)
movsd %xmm0, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x68(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x38(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq 0x10(%rbp), %rdx
movq 0x30(%rbp), %r9
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x2cfdc0
movq -0x68(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x2dcf12
movl $0x0, -0x24(%rbp)
jmp 0x2dd34a
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
movq 0x10(%rbp), %rdx
movq 0x18(%rbp), %rcx
movq 0x20(%rbp), %r8
movsd -0x60(%rbp), %xmm0
movq -0x38(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, %r9d
movq 0x38(%rbp), %rax
movq %rax, (%rsp)
callq 0x2d1530
movq -0x68(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x2dcf4f
jmp 0x2dcf6e
leaq 0xb6ff5(%rip), %rdi     # 0x393f4b
leaq 0xb38d2(%rip), %rsi     # 0x39082f
movl $0x3f24, %edx           # imm = 0x3F24
leaq 0xb6fe9(%rip), %rcx     # 0x393f52
callq 0x2130
movq -0x68(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x2dcf85
movl $0x0, -0x24(%rbp)
jmp 0x2dd34a
movq 0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x68(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x38(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, %ecx
movq 0x30(%rbp), %r8
callq 0x2d2df0
movq -0x48(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x2dcfbd
movl $0x0, -0x24(%rbp)
jmp 0x2dd34a
jmp 0x2dcfbf
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rax
movq -0x48(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x2dd0a0
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
shrq %rcx
movq -0x40(%rbp), %rax
orq 0x50(%rax), %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
shrq $0x2, %rcx
movq -0x40(%rbp), %rax
orq 0x50(%rax), %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
shrq $0x4, %rcx
movq -0x40(%rbp), %rax
orq 0x50(%rax), %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
shrq $0x8, %rcx
movq -0x40(%rbp), %rax
orq 0x50(%rax), %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
shrq $0x10, %rcx
movq -0x40(%rbp), %rax
orq 0x50(%rax), %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rdi
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x58(%rax)
jmp 0x2dd0a2
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xc8(%rbp)
movq 0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb8(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x48(%rbp), %rax
addq $0x18, %rax
movq %rax, -0xa8(%rbp)
movq -0x48(%rbp), %rax
addq $0x30, %rax
movq %rax, -0xa0(%rbp)
movq -0x48(%rbp), %rax
addq $0x48, %rax
movq %rax, -0x98(%rbp)
movq -0x48(%rbp), %rax
addq $0x60, %rax
movq %rax, -0x90(%rbp)
movq -0x38(%rbp), %rax
movl 0x18(%rax), %eax
movq %rax, -0x88(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, 0x48(%rbp)
je 0x2dd13f
movsd 0xa5143(%rip), %xmm0    # 0x382278
movsd %xmm0, -0xd0(%rbp)
jmp 0x2dd14c
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0xd0(%rbp)
movq -0x80(%rbp), %rbx
movq -0x88(%rbp), %r14
movq -0x90(%rbp), %r15
movq -0x98(%rbp), %r12
movq -0xa0(%rbp), %r9
movq -0xa8(%rbp), %r8
movq -0xb0(%rbp), %rcx
movq -0xb8(%rbp), %rdx
movq -0xc0(%rbp), %rsi
movq -0xc8(%rbp), %rdi
movsd -0xd0(%rbp), %xmm0
movq -0x40(%rbp), %rax
movq 0x58(%rax), %r11
movq -0x50(%rbp), %r10
movq 0x38(%rbp), %rax
movsd 0xa1e81(%rip), %xmm1    # 0x37f030
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq $0x10, 0x20(%rsp)
movq %r11, 0x28(%rsp)
movq %r10, 0x30(%rsp)
movq %rax, 0x38(%rsp)
movq $0x48, 0x40(%rsp)
movq $0x1388, 0x48(%rsp)     # imm = 0x1388
movq $0xc350, 0x50(%rsp)     # imm = 0xC350
movq $0x1, 0x58(%rsp)
callq 0x2a4e00
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
jl 0x2dd343
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq 0x10(%rbp), %rsi
movq 0x30(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x40(%rbp), %r9
addq $0x18, %r9
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %r14
movq -0x48(%rbp), %rbx
addq $0xa8, %rbx
movq -0x48(%rbp), %r11
addq $0x48, %r11
movq -0x48(%rbp), %r10
addq $0x60, %r10
movq -0x48(%rbp), %rax
addq $0x18, %rax
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x2a85f0
movl %eax, %eax
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
je 0x2dd341
cmpq $0x0, 0x48(%rbp)
je 0x2dd2d1
cmpq $0x0, 0x48(%rbp)
je 0x2dd327
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x14(%rax), %ecx
movl 0x18(%rax), %eax
subl %ecx, %eax
cvtsi2sd %eax, %xmm0
movq -0x38(%rbp), %rax
movl 0x18(%rax), %eax
cvtsi2sd %rax, %xmm1
movsd 0xb3489(%rip), %xmm2    # 0x390750
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2dd327
movq 0x10(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x70(%rbp), %rdx
movq -0x38(%rbp), %rcx
movq -0x48(%rbp), %r8
addq $0x18, %r8
movq -0x48(%rbp), %r9
movq 0x30(%rbp), %r11
movq 0x40(%rbp), %r10
movq 0x38(%rbp), %rax
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movq $0x48, 0x18(%rsp)
movq $0x1388, 0x20(%rsp)     # imm = 0x1388
movq $0xc350, 0x28(%rsp)     # imm = 0xC350
callq 0x2dc340
movq -0x38(%rbp), %rax
movzbl 0x50(%rax), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x1, %edx
cmovel %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0x2dd34a
jmp 0x2dd343
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
addq $0x110, %rsp            # imm = 0x110
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)