// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/inter.cpp
// Function: cl_trans_gen(unsigned int, unsigned int, ul_vec_t*, kv_ul_ov_t*, ul_idx_t const*, ma_ug_t*, scaf_res_t*, ma_ug_t*, bubble_type*, kv_u_trans_t*, unsigned int, unsigned int)
void cl_trans_gen(uint32_t qid, uint32_t qlen, ul_vec_t *qstr, kv_ul_ov_t *res, const ul_idx_t *uref, ma_ug_t *ref, scaf_res_t *ref_sc, ma_ug_t *gfa, bubble_type *bub, kv_u_trans_t *ta, uint32_t is_self, uint32_t is_exact)
{
    uint64_t k, l, m = 0, mi, z, zn, a_n, bid, nw; uc_block_t *a; uint32_t avid = ((is_self)?(qid):((uint32_t)-1));
    res->n = 0;
	///identify bubble chain first
	for (k = 0, a = qstr->bb.a; k < qstr->bb.n; k++) {
		z = qstr->bb.a[k].ts; a_n = qstr->bb.a[k].te;
		while (z < a_n) {
			zn = 1;
			zn = pick_bubble(a + z, a_n - z, bub, &bid);
			if((!zn) || (!qry_bub_sc(uref, gfa, ref_sc, bub, bid, z, z + zn, qstr, avid, res))) {///found a bubble; a[z] -> beg; a[z + zn] -> sink
				zn = 1;
			}
			z += zn;
		}
	}

	if(res->n) {///matched bubbles
		for (k = 0; k < res->n; k++) res->a[k].tn = (((uint64_t)res->a[k].tn)<<1)|((uint64_t)res->a[k].rev);
		radix_sort_ul_ov_srt_tn(res->a, res->a + res->n);

		for (k = 1, l = m = 0; k <= res->n; k++) {
			if(k == res->n || res->a[k].tn != res->a[l].tn) {///qn <- (tn|rev)
				for (z = l; z < k; z++) res->a[z].tn>>=1;
				a_n = k;
				if(k - l > 1) {///if there is only one alignment for a node, then no need for DP
					a_n = l + cc_bub_match(res->a+l, k-l);
				}
				
				for (z = l; z < a_n; z++) res->a[m++] = res->a[z];
				// fprintf(stderr, "l::%lu, k::%lu, m::%lu\n", l, k, m);
				l = k;
			}
		}
    	res->n = m;
		radix_sort_ul_ov_srt_qe(res->a, res->a + res->n);
		// for (k = 0; k < res->n; k++) {
		// 	fprintf(stderr, "***qsidx::%u(utg%.6u%c), qeidx::%u(utg%.6u%c)\n", res->a[k].qs, (qstr->bb.a[res->a[k].qs].hid)+1, "lc"[gfa->u.a[qstr->bb.a[res->a[k].qs].hid].circ], res->a[k].qe, (qstr->bb.a[res->a[k].qe].hid)+1, "lc"[gfa->u.a[qstr->bb.a[res->a[k].qe].hid].circ]);
		// }
		
	}

	for (k = 0; k < qstr->bb.n; k++) {
		z = qstr->bb.a[k].ts; a_n = qstr->bb.a[k].te;
		for (; z < a_n; z++) {
			///filter by bubble
			for (mi = 0; mi < m && z <= res->a[mi].qe; mi++) {
				if((z >= res->a[mi].qs) && (z <= res->a[mi].qe)) break;
			}
			if((mi < m) && (z >= res->a[mi].qs) && (z <= res->a[mi].qe)) continue;

			///exact match
			if(extract_scaf_res_t(&(qstr->bb.a[z]), uref, ref_sc, avid, res)) continue;

			///trans match
			extract_trans_scaf_res_t(&(qstr->bb.a[z]), uref, ref_sc, gfa, ta, avid, is_exact, res);
		}
	}

	for(k = 0; k < m; k++) {///reset bubble
		res->a[k].el = 1; res->a[k].qn = res->a[k].qs;

		res->a[k].qs = qstr->bb.a[res->a[k].qs].qs;
		res->a[k].qe = qstr->bb.a[res->a[k].qe].qe;

		res->a[k].ts = ref_sc->a[res->a[k].tn].bb.a[res->a[k].ts].qs;
		res->a[k].te = ref_sc->a[res->a[k].tn].bb.a[res->a[k].te].qe;

		nw = MAX(res->a[k].te-res->a[k].ts, res->a[k].qe-res->a[k].qs); nw *= CHAIN_MATCH; 
		res->a[k].sec = ((nw>=0x3fffffff)?(0x3fffffff):(nw));
	}

	// for (k = 0; k < res->n; k++) {
	// 	fprintf(stderr, "[M::%s]\tutg%.6ul(len::%u)\tq::[%u, %u)\t%c\tutg%.6ul(len::%u)\tt::[%u, %u)\tel::%u\ttp::%u\n", __func__, qid + 1, qlen, res->a[k].qs, res->a[k].qe, "+-"[res->a[k].rev], res->a[k].tn+1, ref->u.a[res->a[k].tn].len, res->a[k].ts, res->a[k].te, res->a[k].el, res->a[k].qn);
	// }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, 0x10(%rsp)
xorl %esi, %esi
cmpl $0x1, 0x80(%rsp)
sbbl %esi, %esi
movq $0x0, 0x8(%rcx)
movq %rdx, (%rsp)
movq 0x20(%rdx), %rax
testq %rax, %rax
je 0x1d823b
movq %rcx, %r15
movq 0x70(%rsp), %rbp
orl %edi, %esi
movq %rsi, 0x8(%rsp)
movq (%rsp), %rcx
movq 0x30(%rcx), %r13
xorl %esi, %esi
movq (%rsp), %rcx
movq 0x30(%rcx), %rcx
leaq (%rsi,%rsi,8), %rdx
movl 0xc(%rcx,%rdx,4), %r14d
movl 0x10(%rcx,%rdx,4), %ebx
cmpl %ebx, %r14d
jae 0x1d7f41
movq %rsi, 0x18(%rsp)
leaq (%r14,%r14,8), %rax
leaq (,%rax,4), %rdi
addq %r13, %rdi
movq %rbx, %rsi
subq %r14, %rsi
movq %rbp, %rdx
leaq 0x20(%rsp), %rcx
callq 0x1d7119
testq %rax, %rax
je 0x1d7f26
movq %rax, %r12
movq 0x20(%rsp), %r8
addq %r14, %rax
movq 0x10(%rsp), %rdi
movq 0x60(%rsp), %rdx
movq %rbp, %rcx
movq %r14, %r9
pushq %r15
pushq 0x10(%rsp)
pushq 0x10(%rsp)
pushq %rax
callq 0x1d71cf
addq $0x20, %rsp
testq %rax, %rax
jne 0x1d7f2c
movl $0x1, %r12d
addq %r12, %r14
cmpq %rbx, %r14
jb 0x1d7ecb
movq (%rsp), %rax
movq 0x20(%rax), %rax
movq 0x18(%rsp), %rsi
incq %rsi
cmpq %rax, %rsi
jb 0x1d7eac
movq %r15, %rbx
movq 0x8(%r15), %rcx
testq %rcx, %rcx
je 0x1d807a
movq (%rbx), %rdi
leaq 0xc(%rdi), %rax
movq %rcx, %rdx
movl 0xc(%rax), %esi
shldl $0x1, %esi, (%rax)
addq $0x1c, %rax
decq %rdx
jne 0x1d7f67
leaq (%rcx,%rcx,8), %rax
leaq (%rax,%rax,2), %rsi
addq %rcx, %rsi
addq %rdi, %rsi
callq 0x19e855
movq 0x8(%rbx), %rax
testq %rax, %rax
je 0x1d807f
movl $0x1, %r14d
xorl %r12d, %r12d
xorl %r15d, %r15d
cmpq %rax, %r14
je 0x1d7fcf
movq (%rbx), %rax
leaq (%r14,%r14,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %r14, %rcx
movl 0xc(%rax,%rcx), %ecx
leaq (%r12,%r12,8), %rdx
leaq (%rdx,%rdx,2), %rdx
addq %r12, %rdx
cmpl 0xc(%rax,%rdx), %ecx
je 0x1d8068
movq %r14, %rsi
subq %r12, %rsi
jbe 0x1d7ffd
movq (%rbx), %rax
leaq (%r12,%r12,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %r12, %rcx
addq %rcx, %rax
addq $0xc, %rax
movq %r12, %rcx
shrl (%rax)
incq %rcx
addq $0x1c, %rax
cmpq %rcx, %r14
jne 0x1d7fef
movq %r14, %rax
cmpq $0x2, %rsi
jb 0x1d801c
leaq (%r12,%r12,8), %rax
leaq (%rax,%rax,2), %rdi
addq %r12, %rdi
addq (%rbx), %rdi
callq 0x1d781b
addq %r12, %rax
movq %rax, %rcx
subq %r12, %rcx
jbe 0x1d8065
addq %r15, %rax
subq %r12, %rax
leaq (%r15,%r15,8), %rdx
leaq (%rdx,%rdx,2), %rdx
addq %r15, %rdx
leaq (%r12,%r12,8), %rsi
leaq (%rsi,%rsi,2), %rsi
addq %r12, %rsi
movq (%rbx), %rdi
movups (%rdi,%rsi), %xmm0
movups 0xc(%rdi,%rsi), %xmm1
movups %xmm1, 0xc(%rdi,%rdx)
movups %xmm0, (%rdi,%rdx)
addq $0x1c, %rdx
addq $0x1c, %rsi
decq %rcx
jne 0x1d8040
movq %rax, %r15
movq %r14, %r12
incq %r14
movq 0x8(%rbx), %rax
cmpq %rax, %r14
jbe 0x1d7fa3
jmp 0x1d8082
xorl %r15d, %r15d
jmp 0x1d80a4
xorl %r15d, %r15d
movq %r15, 0x8(%rbx)
movq (%rbx), %rdi
leaq (%r15,%r15,8), %rax
leaq (%rax,%rax,2), %rsi
addq %r15, %rsi
addq %rdi, %rsi
callq 0x19e2b4
movq (%rsp), %rax
movq 0x20(%rax), %rax
testq %rax, %rax
je 0x1d8181
xorl %r12d, %r12d
movq (%rsp), %rcx
movq 0x30(%rcx), %rcx
leaq (%r12,%r12,8), %rdx
movl 0xc(%rcx,%rdx,4), %r13d
movl 0x10(%rcx,%rdx,4), %ebp
cmpl %ebp, %r13d
jae 0x1d8175
testq %r15, %r15
je 0x1d80f5
movq (%rbx), %rax
addq $0x8, %rax
movq %r15, %rcx
movl (%rax), %edx
cmpq %rdx, %r13
ja 0x1d80f5
movl -0x4(%rax), %edx
cmpq %rdx, %r13
jae 0x1d8161
addq $0x1c, %rax
decq %rcx
jne 0x1d80dd
leaq (,%r13,8), %r14
addq %r13, %r14
shlq $0x2, %r14
movq (%rsp), %rax
movq 0x30(%rax), %rdi
addq %r14, %rdi
movq 0x10(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x8(%rsp), %rcx
movq %rbx, %r8
callq 0x1d79b0
testq %rax, %rax
jne 0x1d8161
movq (%rsp), %rax
addq 0x30(%rax), %r14
movq %r14, %rdi
movq 0x10(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x68(%rsp), %rcx
movq 0x78(%rsp), %r8
movq 0x8(%rsp), %r9
pushq %rbx
movl 0x90(%rsp), %eax
pushq %rax
callq 0x1d7c51
addq $0x10, %rsp
incq %r13
cmpq %rbp, %r13
jne 0x1d80ce
movq (%rsp), %rax
movq 0x20(%rax), %rax
incq %r12
cmpq %rax, %r12
jb 0x1d80b0
testq %r15, %r15
je 0x1d823b
movl $0x18, %eax
movl $0xc0000000, %ecx       # imm = 0xC0000000
movq (%rbx), %rdx
orl $0x40000000, (%rdx,%rax) # imm = 0x40000000
movq (%rbx), %rdx
movl -0x14(%rdx,%rax), %esi
movl -0x10(%rdx,%rax), %edi
movl %esi, -0x18(%rdx,%rax)
movq (%rsp), %r8
movq 0x30(%r8), %r8
leaq (%rsi,%rsi,8), %rsi
movl 0x4(%r8,%rsi,4), %r9d
movl %r9d, -0x14(%rdx,%rax)
leaq (%rdi,%rdi,8), %rsi
movl 0x8(%r8,%rsi,4), %esi
movl %esi, -0x10(%rdx,%rax)
movq 0x60(%rsp), %rdi
movq (%rdi), %rdi
movl -0xc(%rdx,%rax), %r8d
imulq $0x58, %r8, %r8
movq 0x30(%rdi,%r8), %rdi
movl -0x8(%rdx,%rax), %r8d
leaq (%r8,%r8,8), %r8
movl 0x4(%rdi,%r8,4), %r8d
movl %r8d, -0x8(%rdx,%rax)
movl -0x4(%rdx,%rax), %r10d
leaq (%r10,%r10,8), %r10
movl 0x8(%rdi,%r10,4), %edi
movl %edi, -0x4(%rdx,%rax)
subl %r8d, %edi
subl %r9d, %esi
cmpl %esi, %edi
cmoval %edi, %esi
movl $0x3fffffff, %edi       # imm = 0x3FFFFFFF
cmpl %edi, %esi
jb 0x1d8224
movl $0x3fffffff, %esi       # imm = 0x3FFFFFFF
movl (%rdx,%rax), %edi
andl %ecx, %edi
orl %esi, %edi
movl %edi, (%rdx,%rax)
addq $0x1c, %rax
decq %r15
jne 0x1d8194
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq