// File: /workspace/github_cpp_makefile_star2_O2/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 $0x78, %rsp
movq %rcx, %r13
movq 0x110(%rsp), %r15
imulq $0x1c, %rdx, %rbx
imulq $0x1c, %rcx, %rsi
movl 0xc(%rdi,%rbx), %eax
movl 0x18(%rdi,%rbx), %ebp
shrdl $0x1f, %eax, %ebp
movl 0xc(%rdi,%rsi), %eax
movl 0x18(%rdi,%rsi), %r12d
andl $0x0, (%r15)
shrdl $0x1f, %eax, %r12d
movq $-0x80000000, %rcx      # imm = 0x80000000
cmpl %r12d, %ebp
je 0x1737fe
movq %rdi, %r14
addq %rdi, %rbx
addq %rdi, %rsi
movl 0x8(%rsi), %eax
cmpl 0x4(%rbx), %eax
jbe 0x1737fe
movq %rdx, %r10
movl (%r9,%r13,4), %eax
movl %eax, %ecx
sarl $0x2, %ecx
movslq %ecx, %rcx
cmpq %rdx, %rcx
movq %rsi, 0x70(%rsp)
je 0x173521
movsd %xmm1, 0x40(%rsp)
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r10, %r15
movq %r8, 0x60(%rsp)
movq %r9, 0x48(%rsp)
xorl %r9d, %r9d
movsd %xmm0, 0x50(%rsp)
callq 0x3d261
movq %r15, 0x38(%rsp)
leal 0x3(,%r15,4), %ecx
movq 0x48(%rsp), %r15
movl %ecx, (%r15,%r13,4)
movl %ebp, %edx
xorl $0x1, %edx
xorl $0x1, %r12d
leaq 0x30(%rsp), %rcx
movq %rcx, (%rsp)
movq 0xb8(%rsp), %rsi
movl %r12d, %ecx
movq 0xc0(%rsp), %r8
movsd 0x50(%rsp), %xmm0
movq %rax, %r9
callq 0x1728e0
testq %rax, %rax
je 0x1737f7
movq 0x38(%rsp), %r10
leal (,%r10,4), %eax
movq 0x30(%rsp), %rcx
addl %ecx, %eax
movl %eax, (%r15,%r13,4)
testq %rcx, %rcx
movsd 0x40(%rsp), %xmm1
movq 0x70(%rsp), %rsi
movq %r15, %r9
movsd 0x50(%rsp), %xmm0
movq 0x60(%rsp), %r8
movq 0x110(%rsp), %r15
je 0x173521
andb $-0x41, 0x1b(%rsi)
movl (%r9,%r13,4), %eax
movl %eax, %ecx
notl %ecx
testb $0x3, %cl
je 0x1737f7
movl %eax, %ecx
sarl $0x2, %ecx
movslq %ecx, %rcx
cmpq %r10, %rcx
jne 0x1737f7
andl $0x1, %eax
movq %rax, 0x30(%rsp)
jne 0x173559
testq %r13, %r13
js 0x1736ab
xorl %ebp, %ebp
jmp 0x17373e
movsd %xmm0, 0x50(%rsp)
movq 0xc8(%rsp), %rdi
movq %r13, %r15
movl 0x4(%rsi), %r13d
movl %ebp, %eax
xorl $0x1, %eax
movl %eax, 0x6c(%rsp)
leal (,%r10,4), %eax
movl %eax, 0x68(%rsp)
movq %r15, 0x58(%rsp)
movsd %xmm1, 0x40(%rsp)
movq %r10, 0x38(%rsp)
movq %r9, 0x48(%rsp)
movq %r8, 0x60(%rsp)
movq (%rdi,%r15,8), %r15
testq %r15, %r15
js 0x1736b8
movl (%r9,%r15,4), %eax
movl %eax, %ecx
sarl $0x2, %ecx
movslq %ecx, %rdx
cmpq %r10, %rdx
je 0x17366e
leal 0x3(,%r15,4), %eax
movl %eax, (%r9,%r15,4)
imulq $0x1c, %r15, %rsi
movl 0xc(%r14,%rsi), %ecx
movl 0x18(%r14,%rsi), %r12d
shrdl $0x1f, %ecx, %r12d
cmpl %r12d, %ebp
je 0x17370d
addq %r14, %rsi
movl 0x8(%rsi), %ecx
cmpl 0x4(%rbx), %ecx
jbe 0x17370d
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r9d, %r9d
callq 0x3d261
xorl $0x1, %r12d
leaq 0x30(%rsp), %rcx
movq %rcx, (%rsp)
movq 0xb8(%rsp), %rsi
movl 0x6c(%rsp), %edx
movl %r12d, %ecx
movq 0xc0(%rsp), %r8
movsd 0x50(%rsp), %xmm0
movq %rax, %r9
callq 0x1728e0
testq %rax, %rax
je 0x1736f9
movl 0x30(%rsp), %eax
addl 0x68(%rsp), %eax
movq 0x48(%rsp), %r9
movl %eax, (%r9,%r15,4)
movl %eax, %ecx
sarl $0x2, %ecx
movsd 0x40(%rsp), %xmm1
movq 0x38(%rsp), %r10
movq 0x60(%rsp), %r8
movq 0xc8(%rsp), %rdi
movl %eax, %edx
notl %edx
testb $0x3, %dl
je 0x17370d
movslq %ecx, %rcx
cmpq %r10, %rcx
jne 0x17370d
imulq $0x1c, %r15, %rcx
movl 0x4(%r14,%rcx), %ecx
cmpl %ecx, %r13d
cmovael %ecx, %r13d
movl %eax, %ecx
andl $0x1, %ecx
movq %rcx, 0x30(%rsp)
testb $0x1, %al
jne 0x17359d
jmp 0x17370d
movq %r13, 0x58(%rsp)
movl $0x7fffffff, %r13d      # imm = 0x7FFFFFFF
jmp 0x1736c0
movq 0x110(%rsp), %r15
movl 0x4(%rbx), %eax
movb $0x1, %bpl
cmpl %eax, %r13d
movq 0x58(%rsp), %r13
jbe 0x17373e
movl 0x8(%rbx), %edx
movl 0x18(%rbx), %ecx
subl %eax, %edx
andl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
imulq 0x108(%rsp), %rcx
subq %rcx, %rdx
movq %rdx, %rcx
movl $0x1, (%r15)
jmp 0x1737fe
movq 0x48(%rsp), %rax
movl (%rax,%r15,4), %eax
movsd 0x40(%rsp), %xmm1
movq 0x38(%rsp), %r10
movl %eax, %ecx
notl %ecx
testb $0x3, %cl
movq 0x110(%rsp), %r15
je 0x1737f7
sarl $0x2, %eax
cltq
cmpq %r10, %rax
movq $-0x80000000, %rcx      # imm = 0x80000000
jne 0x1737fe
xorl %ebp, %ebp
movq 0x58(%rsp), %r13
movq 0x100(%rsp), %rax
movq 0xf8(%rsp), %rcx
movq 0xf0(%rsp), %rsi
movq 0xe8(%rsp), %r9
movq 0xe0(%rsp), %rdx
movq 0xd8(%rsp), %rdi
movq 0xd0(%rsp), %r14
movq 0xb0(%rsp), %r8
movq 0x70(%rsp), %r12
movl 0x8(%r12), %r10d
movq %r10, 0x20(%rsp)
movq %rax, 0x18(%rsp)
movq %rcx, 0x8(%rsp)
andq $0x0, 0x10(%rsp)
movq %rsi, (%rsp)
movq %rbx, %rsi
xorl %ecx, %ecx
movaps %xmm1, %xmm0
callq 0x4cafd
movl 0x8(%rbx), %ecx
addl (%r14,%r13,4), %ecx
subl 0x8(%r12), %ecx
movq 0x108(%rsp), %rsi
imulq %rsi, %rax
subq %rax, %rcx
andl $0x0, (%r15)
testb %bpl, %bpl
je 0x1737fe
movl 0x8(%rbx), %eax
movq %rcx, %rdx
movl 0x18(%rbx), %ecx
subl 0x4(%rbx), %eax
andl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
imulq %rsi, %rcx
subq %rcx, %rax
movq %rdx, %rcx
cmpq %rax, %rdx
cmovleq %rax, %rcx
jmp 0x1737fe
movq $-0x80000000, %rcx      # imm = 0x80000000
movq %rcx, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq