// File: 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
movq %rsp, %rbp
pushq %rbx
subq $0xd8, %rsp
movq 0x70(%rbp), %rax
movq 0x68(%rbp), %rax
movq 0x60(%rbp), %rax
movq 0x58(%rbp), %rax
movq 0x50(%rbp), %rax
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, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq %rdx, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x40(%rbp)
movsd %xmm0, -0x48(%rbp)
movsd %xmm1, -0x50(%rbp)
movq -0x18(%rbp), %rax
imulq $0x1c, -0x28(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
imulq $0x1c, -0x30(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movl $0x7fffffff, -0x78(%rbp) # imm = 0x7FFFFFFF
movq $-0x80000000, -0xa8(%rbp) # imm = 0x80000000
movq -0x58(%rbp), %rax
movl 0xc(%rax), %eax
shll %eax
movq -0x58(%rbp), %rcx
movl 0x18(%rcx), %ecx
shrl $0x1f, %ecx
orl %ecx, %eax
movl %eax, -0x6c(%rbp)
movq -0x60(%rbp), %rax
movl 0xc(%rax), %eax
shll %eax
movq -0x60(%rbp), %rcx
movl 0x18(%rcx), %ecx
shrl $0x1f, %ecx
orl %ecx, %eax
movl %eax, -0x70(%rbp)
movq 0x70(%rbp), %rax
movl $0x0, (%rax)
movl -0x6c(%rbp), %eax
cmpl -0x70(%rbp), %eax
jne 0x2b22f3
movq $-0x80000000, -0x10(%rbp) # imm = 0x80000000
jmp 0x2b283a
movq -0x60(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x58(%rbp), %rcx
cmpl 0x4(%rcx), %eax
ja 0x2b2310
movq $-0x80000000, -0x10(%rbp) # imm = 0x80000000
jmp 0x2b283a
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
sarl $0x2, %eax
cltq
cmpq -0x28(%rbp), %rax
je 0x2b2403
movq -0x58(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq -0x38(%rbp), %r8
xorl %eax, %eax
movl %eax, %r9d
movq %r9, %rdx
movq %r9, %rcx
callq 0x71a90
movq %rax, -0x80(%rbp)
movq -0x28(%rbp), %rax
shlq $0x2, %rax
movl %eax, %edx
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x3, %edx
movl %edx, (%rax,%rcx,4)
movq 0x10(%rbp), %rdi
movq 0x18(%rbp), %rsi
movl -0x6c(%rbp), %edx
xorl $0x1, %edx
movl -0x70(%rbp), %ecx
xorl $0x1, %ecx
movq 0x20(%rbp), %r8
movsd -0x48(%rbp), %xmm0
movq -0x80(%rbp), %r9
leaq -0x88(%rbp), %rax
movq %rax, (%rsp)
callq 0x2b0c90
cmpq $0x0, %rax
je 0x2b23f4
movq -0x28(%rbp), %rax
shlq $0x2, %rax
movl %eax, %edx
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x88(%rbp), %rsi
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movslq (%rax,%rcx,4), %rdx
addq %rsi, %rdx
movl %edx, (%rax,%rcx,4)
cmpq $0x0, -0x88(%rbp)
je 0x2b23f2
movq -0x60(%rbp), %rax
movl 0x18(%rax), %ecx
andl $0xbfffffff, %ecx       # imm = 0xBFFFFFFF
orl $0x0, %ecx
movl %ecx, 0x18(%rax)
jmp 0x2b2401
movq $-0x80000000, -0x10(%rbp) # imm = 0x80000000
jmp 0x2b283a
jmp 0x2b2403
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
sarl $0x2, %eax
cltq
cmpq -0x28(%rbp), %rax
jne 0x2b242c
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x3, %eax
cmpl $0x3, %eax
jne 0x2b2439
movq $-0x80000000, -0x10(%rbp) # imm = 0x80000000
jmp 0x2b283a
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x1, %eax
cltq
movq %rax, -0x88(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x98(%rbp)
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x2b26c2
movq -0x18(%rbp), %rax
imulq $0x1c, -0x30(%rbp), %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x78(%rbp)
movq 0x28(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jl 0x2b266c
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
sarl $0x2, %eax
cltq
cmpq -0x28(%rbp), %rax
je 0x2b25cc
movq -0x90(%rbp), %rax
shlq $0x2, %rax
movl %eax, %edx
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x3, %edx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl 0xc(%rax), %eax
shll %eax
movq -0x68(%rbp), %rcx
movl 0x18(%rcx), %ecx
shrl $0x1f, %ecx
orl %ecx, %eax
movl %eax, -0x74(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x74(%rbp), %eax
jne 0x2b2527
jmp 0x2b266c
movq -0x68(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x58(%rbp), %rcx
cmpl 0x4(%rcx), %eax
ja 0x2b253c
jmp 0x2b266c
movq -0x58(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x38(%rbp), %r8
xorl %eax, %eax
movl %eax, %r9d
movq %r9, %rdx
movq %r9, %rcx
callq 0x71a90
movq %rax, -0x80(%rbp)
movq 0x10(%rbp), %rdi
movq 0x18(%rbp), %rsi
movl -0x6c(%rbp), %edx
xorl $0x1, %edx
movl -0x74(%rbp), %ecx
xorl $0x1, %ecx
movq 0x20(%rbp), %r8
movsd -0x48(%rbp), %xmm0
movq -0x80(%rbp), %r9
leaq -0x88(%rbp), %rax
movq %rax, (%rsp)
callq 0x2b0c90
cmpq $0x0, %rax
jne 0x2b2598
jmp 0x2b266c
movq -0x28(%rbp), %rax
shlq $0x2, %rax
movl %eax, %edx
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x88(%rbp), %rsi
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movslq (%rax,%rcx,4), %rdx
addq %rsi, %rdx
movl %edx, (%rax,%rcx,4)
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
sarl $0x2, %eax
cltq
cmpq -0x28(%rbp), %rax
jne 0x2b25fb
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x3, %eax
cmpl $0x3, %eax
jne 0x2b25fd
jmp 0x2b266c
movl -0x78(%rbp), %eax
movq -0x18(%rbp), %rcx
imulq $0x1c, -0x90(%rbp), %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jbe 0x2b2629
movq -0x18(%rbp), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x78(%rbp)
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x1, %eax
cltq
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0x2b264f
jmp 0x2b266c
jmp 0x2b2651
movq 0x28(%rbp), %rax
movq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
jmp 0x2b2495
movq -0x90(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x90(%rbp)
jl 0x2b26c0
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
sarl $0x2, %eax
cltq
cmpq -0x28(%rbp), %rax
jne 0x2b26b3
movq -0x40(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x3, %eax
cmpl $0x3, %eax
jne 0x2b26c0
movq $-0x80000000, -0x10(%rbp) # imm = 0x80000000
jmp 0x2b283a
jmp 0x2b26c2
cmpq $0x0, -0x98(%rbp)
jge 0x2b26dc
movl -0x78(%rbp), %eax
movq -0x58(%rbp), %rcx
cmpl 0x4(%rcx), %eax
ja 0x2b27e8
movq -0x18(%rbp), %rax
imulq $0x1c, -0x30(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq 0x38(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq 0x40(%rbp), %rdx
movq 0x10(%rbp), %r8
movq 0x48(%rbp), %r9
movq 0x50(%rbp), %rbx
movq 0x58(%rbp), %r11
movq 0x60(%rbp), %r10
movsd -0x50(%rbp), %xmm0
movq -0x60(%rbp), %rax
movl 0x8(%rax), %eax
xorl %ecx, %ecx
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x93360
movq %rax, -0xa0(%rbp)
movq 0x30(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x58(%rbp), %rcx
movl 0x8(%rcx), %ecx
movq -0x60(%rbp), %rdx
subl 0x8(%rdx), %ecx
addl %ecx, %eax
movl %eax, %eax
movq -0xa0(%rbp), %rcx
imulq 0x68(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq 0x70(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x98(%rbp)
jge 0x2b27e6
movq -0x58(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x58(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0xb0(%rbp)
movq -0x58(%rbp), %rax
movl 0x18(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movl %eax, %eax
movl %eax, %ecx
imulq 0x68(%rbp), %rcx
movq -0xb0(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0xb0(%rbp), %rax
jge 0x2b27e4
movq -0xb0(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0x2b27e6
jmp 0x2b282f
movq -0x58(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x58(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0xa8(%rbp)
movq -0x58(%rbp), %rax
movl 0x18(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movl %eax, %eax
movl %eax, %ecx
imulq 0x68(%rbp), %rcx
movq -0xa8(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq 0x70(%rbp), %rax
movl $0x1, (%rax)
movq -0xa8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0xd8, %rsp
popq %rbx
popq %rbp
retq
nopl (%rax,%rax)