// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/inter.cpp
// Function: connect_detect(ul_ov_t*, long, long, long, All_reads*, int*, ul_idx_t const*, ug_opt_t const*, long, double, long*, int*, rtrace_iter*, kv_rtrace_t*, char*, UC_Read*, overlap_region_alloc*, bit_extz_t*, double, long, unsigned int*)
int64_t connect_detect(ul_ov_t *a, int64_t a_n, int64_t ai, int64_t aj, All_reads *ridx, int32_t *rch, 
const ul_idx_t *uref, const ug_opt_t *uopt, int64_t bw, double diff, int64_t *p, int32_t *f, rtrace_iter *tc,
kv_rtrace_t *trace, char* qstr, UC_Read *tu, overlap_region_alloc* ol, bit_extz_t *exz, double e_rate, 
int64_t trans_sc, uint32_t *is_fc)
{
	ul_ov_t *li = &(a[ai]), *lj = &(a[aj]), *lk;
	uint32_t li_v, lj_v, lk_v, lqs = INT32_MAX; int64_t qo, is_c, ak, afk, err, sc = INT32_MIN, wsc;
	li_v = (li->tn<<1)|li->rev; lj_v = (lj->tn<<1)|lj->rev; (*is_fc) = 0;
	if(li_v == lj_v) return INT32_MIN;
	//even this pair has a overlap, its length will be very small; just ignore
	if(lj->qe <= li->qs) return INT32_MIN;
	// if(lj->qs >= li->qs) continue;///no contain
	
	if((rch[aj]>>2) != ai) {
		qo = infer_rovlp(li, lj, NULL, NULL, ridx, NULL); ///overlap length in query (UL read)
		rch[aj] = (ai<<2); rch[aj] += 3;
		// fprintf(stderr, "[j::%ld] (id::%u) %.*s\tqo::%ld\n", aj, lj->tn, 
        //             (int)Get_NAME_LENGTH(R_INF, a[aj].tn), Get_NAME(R_INF, a[aj].tn), qo);
		if(get_ecov_contain_adv(uref, uopt, li_v^1, lj_v^1, bw, diff, qo, &is_c)) {
			rch[aj] = (ai<<2); rch[aj] += is_c; if(is_c) lj->el = 0;
		} else {
			// if(li->tn == 20171) {
			// 	fprintf(stderr, "[j::%ld] %.*s\tconnect::0\n", aj,
			// 			(int)Get_NAME_LENGTH(R_INF, a[aj].tn), Get_NAME(R_INF, a[aj].tn));
			// }
			return INT32_MIN;
		}
	}
	// if(li->tn == 20171) {
	// 	fprintf(stderr, "[j::%ld] %.*s\tconnect::%u\n", aj,
	// 			(int)Get_NAME_LENGTH(R_INF, a[aj].tn), Get_NAME(R_INF, a[aj].tn), rch_connect(rch[aj], ai));
	// }
	
	if(!rch_connect(rch[aj], ai)) return INT32_MIN;
	is_c = rch[aj]&1; ak = afk = aj;
	// fprintf(stderr, "+[j::%ld] %.*s\tis_c::%ld\n", aj,
    //                 (int)Get_NAME_LENGTH(R_INF, a[aj].tn), Get_NAME(R_INF, a[aj].tn), is_c);
	if(is_c) {
		lqs = a[aj].qs;
		for (ak = p[aj]; ak >= 0; ak = p[ak]) {
			if((rch[ak]>>2) != ai) {
				rch[ak] = (ak<<2); rch[ak] += 3; 
				lk = &(a[ak]); lk_v = (lk->tn<<1)|lk->rev;
				if(li_v == lk_v) break;
				if(lk->qe <= li->qs) break;
				qo = infer_rovlp(li, lk, NULL, NULL, ridx, NULL); ///overlap length in query (UL read)
				if(!get_ecov_contain_adv(uref, uopt, li_v^1, lk_v^1, bw, diff, qo, &is_c)) break;
				rch[ak] = (ai<<2); rch[ak] += is_c;
			}
			if(!rch_connect(rch[ak], ai)) break;
			if(lqs > a[ak].qs) lqs = a[ak].qs;
			is_c = rch[ak]&1; if(is_c == 0) break;
		}

		afk = ak;
		if((ak >= 0) && (!rch_connect(rch[ak], ai))) return INT32_MIN;///go to a disconnected node
		// if(ak >= 0) {
		// 	if(!rch_connect(rch[ak], ai)) return INT32_MIN;///go to a disconnected node
		// 	for (ak = p[ak]; ak >= 0 && a[afk].qe <= a[ak].qe + 256; ak = p[ak]) {
		// 		if((rch[ak]>>2) != ai) {
		// 			rch[ak] = (ak<<2); rch[ak] += 3; 
		// 			lk = &(a[ak]); lk_v = (lk->tn<<1)|lk->rev;
		// 			if(li_v == lk_v) return INT32_MIN;
		// 			if(lk->qe <= li->qs) return INT32_MIN;
		// 			qo = infer_rovlp(li, lk, NULL, NULL, ridx, NULL); ///overlap length in query (UL read)
		// 			if(!get_ecov_contain_adv(uref, uopt, li_v^1, lk_v^1, bw, diff, qo, &is_c)) return INT32_MIN;
		// 			rch[ak] = (ai<<2); rch[ak] += is_c;
		// 		}
		// 		if(!rch_connect(rch[ak], ai)) return INT32_MIN;
		// 	}
		// }
	}
	// if(li->tn == 6317) {
	// 	fprintf(stderr, "[M::%s::] [j::%ld] %.*s\tis_c::%ld\tafk::%ld\tlqs::%u\n", __func__, aj,
	// 					(int)Get_NAME_LENGTH(R_INF, a[aj].tn), Get_NAME(R_INF, a[aj].tn), is_c, afk, lqs);
	// }
	///afk >=0: reach to one non-contained read, lqs should <= li->qs
	///afk < 0: all reads are contained, lqs >= li->qs
	if((afk >= 0) || (lqs <= li->qs)) {
		lj = &(a[aj]);
		err = get_rid_backward_cigar_err(tc, li, trace, NULL, uref, qstr, tu, ol, NULL, exz, e_rate, lj->qe);
		sc = f[aj] + (li->qe - lj->qe) - (err*trans_sc); (*is_fc) = 0;
		if(afk < 0) {
			wsc = li->qe - li->qs; wsc -= (((int64_t)li->sec)*trans_sc);
			if(sc < wsc) sc = wsc;
		}
	} else {
		sc = li->qe - li->qs; sc -= (((int64_t)li->sec)*trans_sc); (*is_fc) = 1;
	}
	return sc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %r13
leaq (%rdx,%rdx,8), %rax
leaq (%rax,%rax,2), %rbx
addq %rdx, %rbx
leaq (%rcx,%rcx,8), %rax
leaq (%rax,%rax,2), %r12
addq %rcx, %r12
movl 0xc(%rdi,%rbx), %eax
movl 0x18(%rdi,%rbx), %ebp
shrdl $0x1f, %eax, %ebp
movl 0xc(%rdi,%r12), %eax
movl 0x18(%rdi,%r12), %r14d
shrdl $0x1f, %eax, %r14d
movq 0xe0(%rsp), %rax
movl $0x0, (%rax)
movq $-0x80000000, %rcx      # imm = 0x80000000
cmpl %r14d, %ebp
je 0x1b4711
movq %rdi, %r15
addq %rdi, %rbx
addq %rdi, %r12
movl 0x8(%r12), %eax
cmpl 0x4(%rbx), %eax
jbe 0x1b4711
movl (%r9,%r13,4), %eax
sarl $0x2, %eax
cltq
cmpq %rdx, %rax
je 0x1b443e
movsd %xmm1, 0x20(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
movq %rdx, 0x8(%rsp)
xorl %edx, %edx
xorl %ecx, %ecx
movq %r8, 0x30(%rsp)
movq %r9, (%rsp)
xorl %r9d, %r9d
movsd %xmm0, 0x28(%rsp)
callq 0x6f050
movq 0x8(%rsp), %rcx
leal 0x3(,%rcx,4), %ecx
movq (%rsp), %rdx
movl %ecx, (%rdx,%r13,4)
movl %ebp, %edx
xorl $0x1, %edx
xorl $0x1, %r14d
subq $0x8, %rsp
leaq 0x18(%rsp), %rdi
movq 0x90(%rsp), %rsi
movl %r14d, %ecx
movq 0x98(%rsp), %r8
movsd 0x30(%rsp), %xmm0
movq %rax, %r9
pushq %rdi
callq 0x1b3728
addq $0x10, %rsp
testq %rax, %rax
je 0x1b465a
movq 0x8(%rsp), %rdx
leal (,%rdx,4), %eax
movq (%rsp), %r9
movl %eax, (%r9,%r13,4)
movq 0x10(%rsp), %rcx
addl %ecx, %eax
movl %eax, (%r9,%r13,4)
testq %rcx, %rcx
movsd 0x20(%rsp), %xmm1
movsd 0x28(%rsp), %xmm0
movq 0x30(%rsp), %r8
je 0x1b443e
andb $-0x41, 0x1b(%r12)
movl (%r9,%r13,4), %eax
movl %eax, %ecx
notl %ecx
testb $0x3, %cl
je 0x1b465a
movl %eax, %ecx
sarl $0x2, %ecx
movslq %ecx, %rcx
cmpq %rdx, %rcx
jne 0x1b465a
andq $0x1, %rax
movq %rax, 0x10(%rsp)
movq %r13, 0x40(%rsp)
je 0x1b45da
movq 0x98(%rsp), %rsi
movl 0x4(%r12), %edi
movl %ebp, %eax
xorl $0x1, %eax
movl %eax, 0x3c(%rsp)
leal (,%rdx,4), %eax
movl %eax, 0x38(%rsp)
movsd %xmm1, 0x20(%rsp)
movq %rdx, 0x8(%rsp)
movq %r9, (%rsp)
movsd %xmm0, 0x28(%rsp)
movq %r8, 0x30(%rsp)
movq (%rsi,%r13,8), %r13
testq %r13, %r13
js 0x1b45f4
movl (%r9,%r13,4), %eax
sarl $0x2, %eax
cltq
cmpq %rdx, %rax
je 0x1b4594
leal 0x3(,%r13,4), %eax
movl %eax, (%r9,%r13,4)
leaq (,%r13,8), %rax
addq %r13, %rax
leaq (%rax,%rax,2), %rsi
addq %r13, %rsi
movl 0xc(%r15,%rsi), %eax
movl 0x18(%r15,%rsi), %r14d
shrdl $0x1f, %eax, %r14d
cmpl %r14d, %ebp
je 0x1b45f4
addq %r15, %rsi
movl 0x8(%rsi), %eax
cmpl 0x4(%rbx), %eax
jbe 0x1b45f4
movl %edi, 0x1c(%rsp)
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r9d, %r9d
callq 0x6f050
xorl $0x1, %r14d
subq $0x8, %rsp
movq 0x90(%rsp), %rsi
movl 0x44(%rsp), %edx
movl %r14d, %ecx
movq 0x98(%rsp), %r8
movsd 0x30(%rsp), %xmm0
movq %rax, %r9
leaq 0x18(%rsp), %rax
pushq %rax
callq 0x1b3728
addq $0x10, %rsp
testq %rax, %rax
je 0x1b45e1
movq (%rsp), %r9
movl 0x38(%rsp), %ecx
movl %ecx, (%r9,%r13,4)
movl 0x10(%rsp), %eax
addl %ecx, %eax
movl %eax, (%r9,%r13,4)
movsd 0x20(%rsp), %xmm1
movq 0x8(%rsp), %rdx
movq 0x30(%rsp), %r8
movl 0x1c(%rsp), %edi
movq 0x98(%rsp), %rsi
movl (%r9,%r13,4), %eax
movl %eax, %ecx
notl %ecx
testb $0x3, %cl
je 0x1b45f4
movl %eax, %ecx
sarl $0x2, %ecx
movslq %ecx, %rcx
cmpq %rdx, %rcx
jne 0x1b45f4
leaq (,%r13,8), %rcx
addq %r13, %rcx
leaq (%rcx,%rcx,2), %rcx
addq %r13, %rcx
movl 0x4(%r15,%rcx), %ecx
cmpl %ecx, %edi
cmovael %ecx, %edi
andl $0x1, %eax
movq %rax, 0x10(%rsp)
jne 0x1b44af
jmp 0x1b45f4
movl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
jmp 0x1b461b
movsd 0x20(%rsp), %xmm1
movq 0x8(%rsp), %rdx
movq (%rsp), %r9
movl 0x1c(%rsp), %edi
testq %r13, %r13
js 0x1b461b
movl (%r9,%r13,4), %eax
movl %eax, %ecx
notl %ecx
testb $0x3, %cl
je 0x1b465a
sarl $0x2, %eax
cltq
cmpq %rdx, %rax
movq $-0x80000000, %rcx      # imm = 0x80000000
jne 0x1b4711
movq 0xd8(%rsp), %r14
testq %r13, %r13
jns 0x1b4666
movl 0x4(%rbx), %eax
cmpl %eax, %edi
jbe 0x1b4666
movl 0x8(%rbx), %edx
movl 0x18(%rbx), %ecx
subl %eax, %edx
andl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
imulq %r14, %rcx
subq %rcx, %rdx
movq %rdx, %rcx
movq 0xe0(%rsp), %rax
movl $0x1, (%rax)
jmp 0x1b4711
movq $-0x80000000, %rcx      # imm = 0x80000000
jmp 0x1b4711
movq 0xb8(%rsp), %r9
movq 0xb0(%rsp), %rdx
movq 0xa8(%rsp), %rdi
movq 0xa0(%rsp), %r15
movq 0x80(%rsp), %r8
movl 0x8(%r12), %eax
subq $0x8, %rsp
movq %rbx, %rsi
xorl %ecx, %ecx
movaps %xmm1, %xmm0
pushq %rax
pushq 0xe0(%rsp)
pushq $0x0
pushq 0xe8(%rsp)
pushq 0xe8(%rsp)
callq 0x80597
addq $0x30, %rsp
movl 0x8(%rbx), %edx
movq 0x40(%rsp), %rcx
addl (%r15,%rcx,4), %edx
movq %rdx, %rcx
subl 0x8(%r12), %ecx
imulq %r14, %rax
subq %rax, %rcx
movq 0xe0(%rsp), %rax
movl $0x0, (%rax)
testq %r13, %r13
jns 0x1b4711
movl 0x8(%rbx), %eax
movq %rcx, %rdx
movl 0x18(%rbx), %ecx
subl 0x4(%rbx), %eax
andl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
imulq %r14, %rcx
subq %rcx, %rax
movq %rdx, %rcx
cmpq %rax, %rdx
cmovleq %rax, %rcx
movq %rcx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq