// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/inter.cpp
// Function: quick_rechain(overlap_region_alloc*, ul_ov_t*, long, kv_rtrace_t*, ul_idx_t const*, ug_opt_t const*, long, double, long, long, long, long, bit_extz_t*, long, All_reads*, char*, UC_Read*, double, int*, int*, int*, int*, long*, long*)
int64_t quick_rechain(overlap_region_alloc* ol, ul_ov_t *a, int64_t a_n, kv_rtrace_t *trace, const ul_idx_t *uref, const ug_opt_t *uopt, 
int64_t bw, double diff_ec_ul, int64_t qlen, int64_t max_skip, int64_t max_iter, int64_t max_dis, 
bit_extz_t *exz, int64_t trans_sc, All_reads *ridx, char* qstr, UC_Read *tu, double e_rate, 
int32_t *f, int32_t *c_n, int32_t *c_sc, int32_t *rch, int64_t *p, int64_t *t)
{
	int64_t mm_ovlp, x, i, j, sc, csc, mm_sc, mm_idx, mm_n, sn, n_skip, end_j; 
	ul_ov_t *li, *lj; rtrace_iter tc; int64_t st, max_ii, max, max_n; uint32_t li_v;
	memset(t, 0, (a_n*sizeof((*t)))); 

	for (i = st = 0, max_ii = -1; i < a_n; ++i) {
        li = &(a[i]); li_v = (li->tn<<1)|li->rev; rch[i] = INT32_MAX;
		csc = li->qe - li->qs; csc -= (((int64_t)li->sec)*trans_sc);
        mm_sc = INT32_MIN; mm_idx = -1; mm_n = 0; 
        n_skip = 0; end_j = -1; tc.k = INT32_MAX;
		// if((i>=15) && (rch_connect(rch[15], 18))) {
		// 	fprintf(stderr, ">>>[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
		// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
		// 				"+-"[a[i].rev], rch[15]);
		// }
		if(li->el) {
			mm_ovlp = max_ovlp_src_contain(uopt, li_v^1);        
			x = (li->qs + mm_ovlp)*diff_ec_ul; 
			if(x < bw) x = bw; 
			x += li->qs + mm_ovlp;
			if (x > qlen+1) x = qlen+1;
			x = find_ul_ov_max(i, a, x+G_CHAIN_INDEL); 
			if ((x-st) > max_iter) st = x-max_iter;
			for (j = x; j >= st; --j) { // collect potential destination vertices
				lj = &(a[j]); 
				rch[j] = (i<<2); rch[j] += 3;//set it to unaviable
				// if((i>=15) && (rch_connect(rch[15], 18))) {
				// 	fprintf(stderr, "**j::%ld**[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", j, i, li->tn,
				// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
				// 				"+-"[a[i].rev], rch[15]);
				// }
				if(!(lj->el)) continue;
				if(lj->qe <= li->qs) break;//even this pair has a overlap, its length will be very small; just ignore
				if(lj->qs > li->qs) continue;///no contain
				sc = quick_rechain_sc(a, ol, uref, uopt, bw, diff_ec_ul, ridx, trace, qstr, tu, 
				&tc, e_rate, exz, trans_sc, f, i, j);
				if(sc == INT32_MIN) continue;
				// if(li->tn == 23989) {
				// 	fprintf(stderr, "*[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
				// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
				// 		"+-"[a[i].rev], j, (int)Get_NAME_LENGTH(R_INF, lj->tn), Get_NAME(R_INF, lj->tn));
				// }
				rch[j] = (i<<2);//set it to aviable
				sn = c_n[j] + 1;
				if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
					mm_sc = sc, mm_idx = j; mm_n = sn; 
					if (n_skip > 0) --n_skip;
				} else if (t[j] == i) {
					if (++n_skip > max_skip)
						break;
				}
				if (p[j] >= 0) t[p[j]] = i;
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>1[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }

			end_j = j;
			if (max_ii < 0 || (a[i].qe>(a[max_ii].qe+max_dis))) {//too long
				max = INT32_MIN; max_n = INT32_MIN; max_ii = -1;
				for (j = i - 1; (j >= st) && (a[i].qe<=(max_dis+a[j].qe)); --j) {
					if ((max < f[j]) || ((max == f[j]) && (max_n < c_n[j]))) {
						max = f[j]; max_n = c_n[j]; max_ii = j;
					}
				}
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>2[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }

			if (max_ii >= 0 && max_ii < end_j) {///just have a try with a[i]<->a[max_ii]
				lj = &(a[max_ii]); 
				if((lj->el) && (lj->qe > li->qs) && (lj->qs <= li->qs)) {
					sc = quick_rechain_sc(a, ol, uref, uopt, bw, diff_ec_ul, ridx, trace, qstr, tu, 
					&tc, e_rate, exz, trans_sc, f, i, max_ii);
					///as max_ii < end_j, get_rid_backward_cigar_err still works
					if(sc != INT32_MIN) {
						sn = c_n[max_ii] + 1;
						if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
							mm_sc = sc; mm_idx = max_ii; mm_n = sn; 
						}
					}
				}
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>3[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }
			sc = csc; sn = 1;///for i itself
			if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
				mm_sc = sc, mm_idx = -1; mm_n = sn; 
			}

			if(mm_sc < 0) {
				mm_sc = csc; mm_idx = -1; mm_n = 1;
			}
			// if(li->tn == 23989) {
			// 	fprintf(stderr, "+[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
			// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 		"+-"[a[i].rev], mm_idx, mm_idx>=0?((int)Get_NAME_LENGTH(R_INF, a[mm_idx].tn)):(1), 
			// 		mm_idx>=0?(Get_NAME(R_INF, a[mm_idx].tn)):("*"));
			// }
			if(mm_idx >= 0) {
				///mo meed to update mm_sc and is_fc
				quick_rechain_propagate_transitive_reduction(uref, uopt, ridx, bw, diff_ec_ul, a, x+1, i, rch, f, p, c_n, t, &mm_sc, &mm_idx, &mm_n);
			}
			// if(li->tn == 23989) {
			// 	fprintf(stderr, "-[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
			// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 		"+-"[a[i].rev], mm_idx, mm_idx>=0?((int)Get_NAME_LENGTH(R_INF, a[mm_idx].tn)):(1), 
			// 		mm_idx>=0?(Get_NAME(R_INF, a[mm_idx].tn)):("*"));
			// }
		}
		f[i] = mm_sc; p[i] = mm_idx; c_n[i] = mm_n; 
		if ((max_ii < 0) || ((a[i].qe<=max_dis+a[max_ii].qe) && (f[max_ii]<f[i]))) {
			max_ii = i;
		}
	}

	int64_t cl = 0; i = a_n-1; 
	while (i >= 0) {
		// fprintf(stderr, "i::%ld[M::%s] (id::%u)%.*s\t%c\tq::[%u, %u)\tt::[%u, %u)\tc::%u\n", 
		// i, __func__, a[i].tn, (int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
		// 			"+-"[a[i].rev], a[i].qs, a[i].qe, a[i].ts, a[i].te, !a[i].el);
        t[cl++] = i; i = p[i];
    }
	return cl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movsd %xmm1, 0x78(%rsp)
movsd %xmm0, 0x38(%rsp)
movq %r9, 0x30(%rsp)
movq %r8, 0x58(%rsp)
movq %rcx, 0x70(%rsp)
movq %rdx, %rbx
movq %rsi, %r13
movq %rdi, 0x68(%rsp)
movq 0x1f8(%rsp), %rdi
movq 0x1f0(%rsp), %rbp
leaq (,%rdx,8), %rdx
xorl %esi, %esi
callq 0x20e0
testq %rbx, %rbx
jle 0x1b537c
movq 0x1e8(%rsp), %r11
movq 0x188(%rsp), %rax
incq %rax
movq %rax, 0x98(%rsp)
leaq 0x4(%r13), %rax
movq %rax, 0x90(%rsp)
leaq -0x14(%r13), %rdx
movq $-0x1, %rdi
xorl %r12d, %r12d
movq $-0x1, %r10
xorl %r14d, %r14d
movq %rbx, 0xa0(%rsp)
movq %r13, 0x88(%rsp)
leaq (%r14,%r14,8), %rax
leaq (%rax,%rax,2), %rcx
addq %r14, %rcx
leaq (%rcx,%r13), %r8
movl 0xc(%r13,%rcx), %esi
movl 0x18(%r13,%rcx), %eax
movl $0x7fffffff, (%r11,%r14,4) # imm = 0x7FFFFFFF
movl 0x8(%r13,%rcx), %r9d
movl 0x18(%r13,%rcx), %r15d
subl 0x4(%r13,%rcx), %r9d
movq $-0x1, 0x10(%rsp)
movq $0x0, 0x8(%rsp)
movq $0x7fffffff, 0xb0(%rsp) # imm = 0x7FFFFFFF
movq %r15, 0xa8(%rsp)
btl $0x1e, %r15d
jb 0x1b4d4b
movq $-0x80000000, %rsi      # imm = 0x80000000
jmp 0x1b52b6
movq %r9, 0x20(%rsp)
movq %r10, 0x40(%rsp)
movq %rdi, 0x48(%rsp)
movq %rdx, 0x50(%rsp)
shldl $0x1, %eax, %esi
xorl $0x1, %esi
movq 0x30(%rsp), %rdi
movq %r8, %rbx
callq 0x1b4723
movq %rbx, (%rsp)
movl 0x4(%rbx), %ecx
addq %rax, %rcx
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
mulsd 0x38(%rsp), %xmm0
cvttsd2si %xmm0, %rdx
movq 0x180(%rsp), %rax
cmpq %rax, %rdx
cmovleq %rax, %rdx
addq %rcx, %rdx
movq 0x98(%rsp), %rax
cmpq %rax, %rdx
cmovgeq %rax, %rdx
subl $-0x80, %edx
movl %r14d, %edi
movq %r13, %rsi
callq 0x19f679
movl %eax, 0x60(%rsp)
movslq %eax, %r15
movq %r15, %rax
subq %r12, %rax
movq %r15, %rcx
movq 0x198(%rsp), %rdx
subq %rdx, %rcx
cmpq %rdx, %rax
cmovgq %rcx, %r12
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rax
movq %rax, 0x80(%rsp)
cmpq %r15, %r12
jle 0x1b4e19
movq $-0x80000000, 0x18(%rsp) # imm = 0x80000000
movq %rbp, %rcx
movq %r15, %rax
movq 0x1e8(%rsp), %r11
movq 0x40(%rsp), %r10
jmp 0x1b4fe8
leal (,%r14,4), %eax
movl %eax, 0x64(%rsp)
leal 0x3(,%r14,4), %r13d
leaq (%r15,%r15,8), %rax
leaq (%rax,%rax,2), %rbx
movq 0x90(%rsp), %rax
addq %r15, %rax
addq %rax, %rbx
movq $-0x80000000, 0x18(%rsp) # imm = 0x80000000
movq $0x0, 0x28(%rsp)
movq 0x1e8(%rsp), %r11
movq 0x40(%rsp), %r10
movq (%rsp), %rsi
movl %r13d, (%r11,%r15,4)
testb $0x40, 0x17(%rbx)
je 0x1b4e80
movl 0x4(%rsi), %eax
cmpl %eax, 0x4(%rbx)
jbe 0x1b4fe2
cmpl %eax, (%rbx)
jbe 0x1b4e9b
movq %rbp, %rcx
leaq -0x1(%r15), %rax
addq $-0x1c, %rbx
movq %rcx, %rbp
cmpq %r12, %r15
movq %rax, %r15
jg 0x1b4e66
jmp 0x1b4fe8
subq $0x8, %rsp
movq 0x90(%rsp), %rdi
movq 0x70(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq 0x188(%rsp), %r8
movsd 0x40(%rsp), %xmm0
movq 0x1c0(%rsp), %r9
movsd 0x80(%rsp), %xmm1
pushq %r15
pushq %r14
pushq 0x1e8(%rsp)
pushq 0x1d0(%rsp)
pushq 0x1d0(%rsp)
leaq 0xe0(%rsp), %rax
pushq %rax
pushq 0x200(%rsp)
pushq 0x200(%rsp)
pushq 0xb8(%rsp)
callq 0x1b481c
addq $0x50, %rsp
cmpq $-0x80000000, %rax      # imm = 0x80000000
jne 0x1b4f36
movq %rbp, %rcx
movq 0x1e8(%rsp), %r11
movq 0x40(%rsp), %r10
movq (%rsp), %rsi
jmp 0x1b4e83
movq 0x1e8(%rsp), %r11
movl 0x64(%rsp), %ecx
movl %ecx, (%r11,%r15,4)
movq 0x1d8(%rsp), %rcx
movslq (%rcx,%r15,4), %rcx
incq %rcx
cmpq 0x18(%rsp), %rax
movq 0x40(%rsp), %r10
jg 0x1b4f68
jne 0x1b4f90
cmpq %rcx, %rbp
jge 0x1b4f90
xorl %edx, %edx
movq 0x28(%rsp), %rsi
testq %rsi, %rsi
setg %dl
subq %rdx, %rsi
movq %rsi, 0x28(%rsp)
movq %r15, 0x80(%rsp)
movq %rax, 0x18(%rsp)
movq (%rsp), %rsi
jmp 0x1b4fbc
movq 0x1f8(%rsp), %rax
cmpq %r14, (%rax,%r15,8)
movq (%rsp), %rsi
jne 0x1b4fb9
movq 0x28(%rsp), %rax
cmpq 0x190(%rsp), %rax
jge 0x1b4fe2
incq %rax
movq %rax, 0x28(%rsp)
movq %rbp, %rcx
movq 0x1f0(%rsp), %rax
movq (%rax,%r15,8), %rax
testq %rax, %rax
js 0x1b4e83
movq 0x1f8(%rsp), %rdx
movq %r14, (%rdx,%rax,8)
jmp 0x1b4e83
movq %rbp, %rcx
movq %r15, %rax
movq %rcx, 0x8(%rsp)
movq 0x80(%rsp), %rcx
movq %rcx, 0x10(%rsp)
testq %r10, %r10
movq 0xa0(%rsp), %rbx
movq 0x88(%rsp), %r13
movq 0x1d8(%rsp), %rbp
js 0x1b503b
movq (%rsp), %rcx
movl 0x8(%rcx), %ecx
leaq (%r10,%r10,8), %rdx
leaq (%rdx,%rdx,2), %rdx
addq %r10, %rdx
movl 0x8(%r13,%rdx), %edx
addq 0x1a0(%rsp), %rdx
cmpq %rcx, %rdx
jge 0x1b50b6
movq $-0x1, %r10
cmpq %r12, %r14
jle 0x1b50b6
movq (%rsp), %rcx
movl 0x8(%rcx), %ecx
movq $-0x80000000, %rdx      # imm = 0x80000000
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdi
movq $-0x80000000, %r8       # imm = 0x80000000
movl (%rdi), %r9d
addq 0x1a0(%rsp), %r9
cmpq %rcx, %r9
jl 0x1b50b6
movq 0x1d0(%rsp), %r9
movslq (%r9,%rsi,4), %r9
cmpq %r9, %r8
jge 0x1b5094
movslq (%rbp,%rsi,4), %rdx
movq %rsi, %r10
movq %r9, %r8
jmp 0x1b50a6
jne 0x1b50a6
movq %r10, %r15
movslq (%rbp,%rsi,4), %r10
cmpq %r10, %rdx
movq %r15, %r10
jl 0x1b5087
addq $-0x1c, %rdi
leaq -0x1(%rsi), %r9
cmpq %r12, %rsi
movq %r9, %rsi
jg 0x1b5066
testq %r10, %r10
movq 0x1f0(%rsp), %rbp
js 0x1b519d
cmpq %rax, %r10
movq (%rsp), %r8
movq 0x20(%rsp), %rdx
movq 0x18(%rsp), %rsi
jge 0x1b51ab
leaq (%r10,%r10,8), %rax
leaq (%rax,%rax,2), %rax
addq %r10, %rax
testb $0x40, 0x1b(%r13,%rax)
je 0x1b51ab
addq %r13, %rax
movl 0x4(%r8), %ecx
cmpl %ecx, 0x8(%rax)
jbe 0x1b51ab
cmpl %ecx, 0x4(%rax)
ja 0x1b51ab
subq $0x8, %rsp
movq %r13, %rdi
movq 0x70(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq 0x188(%rsp), %r8
movsd 0x40(%rsp), %xmm0
movq 0x1c0(%rsp), %r9
movsd 0x80(%rsp), %xmm1
pushq %r10
pushq %r14
pushq 0x1e8(%rsp)
pushq 0x1d0(%rsp)
pushq 0x1d0(%rsp)
leaq 0xe0(%rsp), %rax
pushq %rax
pushq 0x200(%rsp)
pushq 0x200(%rsp)
pushq 0xb8(%rsp)
movq %r10, %r15
callq 0x1b481c
addq $0x50, %rsp
cmpq $-0x80000000, %rax      # imm = 0x80000000
jne 0x1b532c
movq 0x1e8(%rsp), %r11
movq %r15, %r10
movq (%rsp), %r8
movq 0x20(%rsp), %rdx
movq 0x18(%rsp), %rsi
movq 0xa8(%rsp), %rax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
imulq 0x1b0(%rsp), %rax
subq %rax, %rdx
cmpq %rsi, %rdx
jg 0x1b51d3
jne 0x1b51e8
cmpq $0x0, 0x8(%rsp)
jg 0x1b51e8
movq $-0x1, 0x10(%rsp)
movq $0x1, 0x8(%rsp)
movq %rdx, %rsi
testq %rsi, %rsi
jns 0x1b5202
movq $-0x1, 0x10(%rsp)
movq $0x1, 0x8(%rsp)
movq %rdx, %rsi
cmpq $0x0, 0x10(%rsp)
js 0x1b52ac
movl 0x60(%rsp), %r9d
incl %r9d
subq $0x50, %rsp
leaq 0x58(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x60(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x248(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x228(%rsp), %rax
movq %rax, 0x20(%rsp)
movq %rbp, 0x18(%rsp)
movq %r11, 0x8(%rsp)
movq %r14, (%rsp)
movq 0xa8(%rsp), %rdi
movq %rsi, %rbp
movq 0x80(%rsp), %rsi
movq 0x208(%rsp), %rdx
movq 0x1d0(%rsp), %rcx
movsd 0x88(%rsp), %xmm0
movq %r13, %r8
movq %r10, %r15
callq 0x1b4991
movq %rbp, %rsi
movq 0x240(%rsp), %rbp
movq 0x50(%rsp), %r8
movq %r15, %r10
movq 0x238(%rsp), %r11
addq $0x50, %rsp
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rdi
movq 0x1d0(%rsp), %rax
movl %esi, (%rax,%r14,4)
movq 0x10(%rsp), %rax
movq %rax, (%rbp,%r14,8)
movl 0x8(%rsp), %eax
movq 0x1d8(%rsp), %rcx
movl %eax, (%rcx,%r14,4)
testq %r10, %r10
js 0x1b5314
movl 0x8(%r8), %eax
leaq (%r10,%r10,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %r10, %rcx
movl 0x8(%r13,%rcx), %ecx
addq 0x1a0(%rsp), %rcx
cmpq %rax, %rcx
jl 0x1b5317
movq 0x1d0(%rsp), %rcx
movl (%rcx,%r10,4), %eax
cmpl (%rcx,%r14,4), %eax
jge 0x1b5317
movq %r14, %r10
incq %r14
addq $0x1c, %rdx
incq %rdi
cmpq %rbx, %r14
jne 0x1b4ce2
jmp 0x1b537c
movq 0x1d8(%rsp), %rcx
movslq (%rcx,%r15,4), %rcx
incq %rcx
movq 0x18(%rsp), %rsi
cmpq %rsi, %rax
movq 0x1e8(%rsp), %r11
movq %r15, %r10
movq (%rsp), %r8
movq 0x20(%rsp), %rdx
jg 0x1b536a
jne 0x1b51ab
cmpq %rcx, 0x8(%rsp)
jge 0x1b51ab
movq %r10, 0x10(%rsp)
movq %rcx, 0x8(%rsp)
movq %rax, %rsi
jmp 0x1b51ab
testq %rbx, %rbx
jle 0x1b53a1
decq %rbx
xorl %eax, %eax
movq 0x1f8(%rsp), %rcx
movq %rbx, (%rcx,%rax,8)
incq %rax
movq (%rbp,%rbx,8), %rbx
testq %rbx, %rbx
jns 0x1b538e
jmp 0x1b53a3
xorl %eax, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq