// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/inter.cpp
// Function: cal_gl_chain_lin_sc(ul_ov_t*, int, int, rtrace_iter*, overlap_region*, All_reads*, ma_ug_t*, ul_idx_t const*, ug_opt_t const*, long, double, unsigned long, long, long, int*, long)
int64_t cal_gl_chain_lin_sc(ul_ov_t *a, int32_t ai, int32_t aj, rtrace_iter *tc, overlap_region *ol, All_reads *ridx, ma_ug_t *ug, 
const ul_idx_t *uref, const ug_opt_t *uopt, int64_t bw, double diff_ec_ul, uint64_t mode, int64_t trans_sc, int64_t sec_sec, 
int32_t *f, int64_t debug_i)
{
	ul_ov_t *li = &(a[ai]), *lj = &(a[aj]); 
	///li is the suffix of lj
	if(lj->qs >= li->qs) return INT32_MIN;
	uint32_t li_v = (li->tn<<1)|li->rev, lj_v = (lj->tn<<1)|lj->rev;
	int64_t qo = infer_rovlp(li, lj, NULL, NULL, ridx, ug), trans_l = 0, sec_err = 0, sc, sc0, el; ///overlap length in query (UL read)
	///li_v == lj_v is possiable
	if(get_ecov_el(uref, uopt, li_v^1, lj_v^1, bw, diff_ec_ul, qo, mode, &el)) {
		trans_l = get_overlap_region_sub_err(&(ol[li->qn]), tc, lj->qe, &sec_err);
		sc = f[aj] + ((int64_t)(li->qe - lj->qe)) - (trans_l*trans_sc) - (sec_err*sec_sec);

		// char *as = NULL; 
		// asprintf(&as, "+[M::utg%.6dl] utg%.6dl, liq::[%u, %u), ljq::[%u, %u), trans_l::%ld, sec_err::%ld, sc::%ld, f[aj]::%d\n", 
		// (int32_t)li->tn+1, (int32_t)lj->tn+1, li->qs, li->qe, lj->qs, lj->qe, trans_l, sec_err, sc, f[aj]);
		// push_vlog(&(overall_zdbg->a[debug_i]), as); free(as); as = NULL;
		// fprintf(stderr, "+[M::utg%.6dl] utg%.6dl, liq::[%u, %u), ljq::[%u, %u), trans_l::%ld, sec_err::%ld, sc::%ld, f[aj]::%d\n", 
		// 	(int32_t)li->tn+1, (int32_t)lj->tn+1, li->qs, li->qe, lj->qs, lj->qe, trans_l, sec_err, sc, f[aj]);
		if((el == 0) && ((trans_l > 0) || (sec_err > 0)) && (lj->qe > li->qs)) {
			rtrace_iter tr; tr.k = INT32_MAX; sc0 = sc;
			sc = f[aj] + aln_sc(ol[(*li).qn], trans_sc, sec_sec);
			trans_l = get_overlap_region_sub_err(&(ol[lj->qn]), &tr, li->qs, &sec_err);
			sc -= (((int64_t)(lj->qe - li->qs)) - (trans_l*trans_sc) - (sec_err*sec_sec));


			// char *as = NULL; 
			// asprintf(&as, "-[M::utg%.6dl] utg%.6dl, liq::[%u, %u), ljq::[%u, %u), trans_l::%ld, sec_err::%ld, sc::%ld, f[aj]::%d\n", 
			// (int32_t)li->tn+1, (int32_t)lj->tn+1, li->qs, li->qe, lj->qs, lj->qe, trans_l, sec_err, sc, f[aj]);
			// push_vlog(&(overall_zdbg->a[debug_i]), as); free(as); as = NULL;

			if(sc < sc0) sc = sc0;
			// fprintf(stderr, "-[M::utg%.6dl] utg%.6dl, liq::[%u, %u), ljq::[%u, %u), trans_l::%ld, sec_err::%ld, sc::%ld, f[aj]::%d, aln_sc::%ld\n", 
			// (int32_t)li->tn+1, (int32_t)lj->tn+1, li->qs, li->qe, lj->qs, lj->qe, trans_l, sec_err, sc, f[aj], aln_sc(ol[(*li).qn], trans_sc, sec_sec));
		}
		// int64_t trans_l_debug, sec_err_debug;
		// trans_l_debug = get_overlap_region_sub_err_debug(&(ol[li->qn]), lj->qe, &sec_err_debug);
		// if(!(trans_l_debug == trans_l && sec_err_debug == sec_err)) {
		// 	fprintf(stderr, "[M::%s::qs->%u] trans_l::%ld, trans_l_debug::%ld, sec_err::%ld, sec_err_debug::%ld\n", 
		// 	__func__, lj->qe, trans_l, trans_l_debug, sec_err, sec_err_debug);
		// }
		// assert(trans_l_debug == trans_l && sec_err_debug == sec_err);
		// if(li->tn == 308 || li->tn == 311 || lj->tn == 305 || lj->tn == 304) {
		// 	fprintf(stderr, "[M::%s::utg%.6dl] utg%.6dl, liq::[%u, %u), ljq::[%u, %u), trans_l::%ld, sec_err::%ld, sc::%ld\n", __func__, 
        //         (int32_t)li->tn+1, (int32_t)lj->tn+1, li->qs, li->qe, lj->qs, lj->qe, trans_l, sec_err, sc);
		// }
		return sc;
	}
	return INT32_MIN;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movslq %esi, %rax
imulq $0x1c, %rax, %rbx
movslq %edx, %r15
imulq $0x1c, %r15, %r14
movl 0x4(%rdi,%r14), %eax
movq $-0x80000000, %r12      # imm = 0x80000000
cmpl 0x4(%rdi,%rbx), %eax
jae 0x16b708
movq %rcx, %r13
movq %r8, 0x10(%rsp)
movq 0xf0(%rsp), %rax
addq %rdi, %rbx
addq %rdi, %r14
movl 0xc(%rbx), %ecx
movl 0x18(%rbx), %ebp
shrdl $0x1f, %ecx, %ebp
movl 0xc(%r14), %ecx
movl 0x18(%r14), %r12d
shrdl $0x1f, %ecx, %r12d
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r9, %r8
movq %rax, %r9
movsd %xmm0, (%rsp)
callq 0x3d261
andq $0x0, 0x8(%rsp)
xorl $0x1, %ebp
xorl $0x1, %r12d
leaq 0x18(%rsp), %r10
movq 0xf8(%rsp), %rdi
movq 0x100(%rsp), %rsi
movl %ebp, %edx
movl %r12d, %ecx
movq 0x108(%rsp), %r8
movsd (%rsp), %xmm0
movq %rax, %r9
pushq %r10
pushq 0x118(%rsp)
callq 0x16b373
popq %rcx
popq %rdx
testq %rax, %rax
je 0x16b701
movq 0x118(%rsp), %r12
movl (%rbx), %eax
imulq $0xa8, %rax, %rdi
addq 0x10(%rsp), %rdi
movl 0x8(%r14), %edx
leaq 0x8(%rsp), %rbp
movq %r13, %rsi
movq %rbp, %rcx
callq 0x16b219
movq %r12, %rdi
movq 0x120(%rsp), %r8
movq 0x128(%rsp), %rcx
movslq (%rcx,%r15,4), %r13
movl 0x8(%rbx), %r12d
movl 0x8(%r14), %ecx
subl %ecx, %r12d
movq (%rbp), %rdx
movq %rax, %rsi
imulq %rdi, %rsi
movq %rdx, %rdi
imulq %r8, %rdi
addq %rsi, %rdi
addq %r13, %r12
subq %rdi, %r12
cmpq $0x0, 0x18(%rsp)
jne 0x16b708
testq %rax, %rax
setg %al
testq %rdx, %rdx
setg %dl
orb %al, %dl
cmpb $0x1, %dl
jne 0x16b708
movl 0x4(%rbx), %edx
cmpl %edx, %ecx
jbe 0x16b708
leaq 0x20(%rsp), %rsi
movq $0x7fffffff, (%rsi)     # imm = 0x7FFFFFFF
movl (%rbx), %eax
imulq $0xa8, %rax, %rax
movq 0x10(%rsp), %rcx
movl 0x20(%rcx,%rax), %r15d
movl 0x28(%rcx,%rax), %ebp
subl %ebp, %r15d
movl 0x30(%rcx,%rax), %eax
movq %rax, (%rsp)
movl (%r14), %eax
imulq $0xa8, %rax, %rdi
addq %rcx, %rdi
leaq 0x8(%rsp), %rcx
callq 0x16b219
movl 0x8(%r14), %ecx
subl 0x4(%rbx), %ecx
leaq 0x8(%rsp), %rdx
movq (%rdx), %rdx
subq (%rsp), %rdx
subq %r15, %rax
imulq 0x118(%rsp), %rax
imulq 0x120(%rsp), %rdx
addq %rbp, %r13
addq %rax, %r13
subq %rcx, %r13
addq %rdx, %r13
cmpq %r12, %r13
cmovgq %r13, %r12
jmp 0x16b708
movq $-0x80000000, %r12      # imm = 0x80000000
movq %r12, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq