// File: /workspace/github_cpp_makefile_star2_O2/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 $0x38, %rsp
movq %r8, 0x20(%rsp)
movq %rcx, %rbx
movq %rdx, %r15
movq 0x80(%rsp), %rbp
xorl %ecx, %ecx
cmpl $0x1, 0x90(%rsp)
movl $0x0, %eax
sbbl %eax, %eax
andq $0x0, 0x8(%rbx)
orl %edi, %eax
movq %rax, 0x18(%rsp)
movq 0x30(%rdx), %r13
movq %rdx, 0x8(%rsp)
cmpq 0x20(%r15), %rcx
jae 0x18b377
movq 0x30(%r15), %rax
movq %rcx, 0x10(%rsp)
imulq $0x24, %rcx, %rcx
movl 0xc(%rax,%rcx), %r14d
movl 0x10(%rax,%rcx), %r15d
movq %r15, %rsi
subq %r14, %rsi
jbe 0x18b365
imulq $0x24, %r14, %rdi
addq %r13, %rdi
movq %rbp, %rdx
leaq 0x30(%rsp), %rcx
callq 0x18a6ab
testq %rax, %rax
je 0x18b35c
movq %rax, %r12
movq 0x30(%rsp), %r8
addq %r14, %rax
movq 0x20(%rsp), %rdi
movq 0x70(%rsp), %rdx
movq %rbp, %rcx
movq %r14, %r9
pushq %rbx
pushq 0x20(%rsp)
pushq 0x18(%rsp)
pushq %rax
callq 0x18a750
addq $0x20, %rsp
testq %rax, %rax
jne 0x18b360
pushq $0x1
popq %r12
addq %r12, %r14
jmp 0x18b308
movq 0x10(%rsp), %rcx
incq %rcx
movq 0x8(%rsp), %r15
jmp 0x18b2e7
movq 0x8(%rbx), %rax
testq %rax, %rax
je 0x18b46a
movq (%rbx), %rdi
leaq 0xc(%rdi), %rcx
movq %rax, %rdx
subq $0x1, %rdx
jb 0x18b3a1
movl 0xc(%rcx), %esi
shldl $0x1, %esi, (%rcx)
addq $0x1c, %rcx
jmp 0x18b38e
imulq $0x1c, %rax, %rsi
addq %rdi, %rsi
callq 0x1574e1
pushq $0x1
popq %r14
xorl %r13d, %r13d
xorl %r12d, %r12d
cmpq 0x8(%rbx), %r14
ja 0x18b455
je 0x18b3d8
movq (%rbx), %rax
imulq $0x1c, %r14, %rcx
movl 0xc(%rax,%rcx), %ecx
imulq $0x1c, %r12, %rdx
cmpl 0xc(%rax,%rdx), %ecx
je 0x18b44d
imulq $0x1c, %r12, %r15
leaq 0xc(%r15), %rax
movq %r12, %rcx
cmpq %r14, %rcx
jae 0x18b3f7
movq (%rbx), %rdx
shrl (%rdx,%rax)
incq %rcx
addq $0x1c, %rax
jmp 0x18b3e3
movq %r14, %rsi
subq %r12, %rsi
movq %r14, %rax
cmpq $0x2, %rsi
jb 0x18b415
imulq $0x1c, %r12, %rdi
addq (%rbx), %rdi
callq 0x18acf3
addq %r12, %rax
imulq $0x1c, %r13, %rcx
cmpq %rax, %r12
jae 0x18b445
movq (%rbx), %rdx
incq %r13
movups (%rdx,%r15), %xmm0
movups 0xc(%rdx,%r15), %xmm1
movups %xmm1, 0xc(%rdx,%rcx)
movups %xmm0, (%rdx,%rcx)
incq %r12
addq $0x1c, %r15
addq $0x1c, %rcx
jmp 0x18b419
movq %r14, %r12
movq 0x8(%rsp), %r15
incq %r14
jmp 0x18b3b7
movq %r13, 0x8(%rbx)
movq (%rbx), %rdi
imulq $0x1c, %r13, %rsi
addq %rdi, %rsi
callq 0x156f5c
jmp 0x18b46d
xorl %r13d, %r13d
movq %r13, 0x28(%rsp)
leaq 0x1(%r13), %r12
xorl %ecx, %ecx
pushq $0x8
popq %rbp
cmpq 0x20(%r15), %rcx
jae 0x18b548
movq 0x30(%r15), %rax
movq %rcx, 0x10(%rsp)
imulq $0x24, %rcx, %rcx
movl 0xc(%rax,%rcx), %r13d
movl 0x10(%rax,%rcx), %r15d
cmpq %r15, %r13
jae 0x18b536
movq %rbp, %rax
movq %r12, %rcx
decq %rcx
je 0x18b4ca
movq (%rbx), %rdx
movl (%rdx,%rax), %esi
cmpq %rsi, %r13
ja 0x18b4ca
movl -0x4(%rdx,%rax), %edx
addq $0x1c, %rax
cmpq %rdx, %r13
jb 0x18b4ab
jmp 0x18b52e
imulq $0x24, %r13, %r14
movq 0x8(%rsp), %rax
movq 0x30(%rax), %rdi
addq %r14, %rdi
movq 0x20(%rsp), %rsi
movq 0x70(%rsp), %rdx
movq 0x18(%rsp), %rcx
movq %rbx, %r8
callq 0x18ae62
testq %rax, %rax
jne 0x18b52e
movq 0x8(%rsp), %rax
addq 0x30(%rax), %r14
movq %r14, %rdi
movq 0x20(%rsp), %rsi
movq 0x70(%rsp), %rdx
movq 0x78(%rsp), %rcx
movq 0x88(%rsp), %r8
movq 0x18(%rsp), %r9
pushq %rbx
movl 0xa0(%rsp), %eax
pushq %rax
callq 0x18b0e2
popq %rax
popq %rcx
incq %r13
jmp 0x18b49c
movq 0x10(%rsp), %rcx
incq %rcx
movq 0x8(%rsp), %r15
jmp 0x18b47b
pushq $0x18
popq %rax
movl $0xc0000000, %ecx       # imm = 0xC0000000
movq 0x28(%rsp), %r11
subq $0x1, %r11
jb 0x18b5fe
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 0x30(%r15), %r8
imulq $0x24, %rsi, %rsi
movl 0x4(%r8,%rsi), %r9d
movl %r9d, -0x14(%rdx,%rax)
imulq $0x24, %rdi, %rsi
movl 0x8(%r8,%rsi), %esi
movl %esi, -0x10(%rdx,%rax)
movq 0x70(%rsp), %rdi
movq (%rdi), %rdi
movl -0xc(%rdx,%rax), %r8d
imulq $0x58, %r8, %r8
movq 0x30(%rdi,%r8), %rdi
movl -0x8(%rdx,%rax), %r8d
imulq $0x24, %r8, %r8
movl 0x4(%rdi,%r8), %r8d
movl %r8d, -0x8(%rdx,%rax)
movl -0x4(%rdx,%rax), %r10d
imulq $0x24, %r10, %r10
movl 0x8(%rdi,%r10), %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 0x18b5eb
movl $0x3fffffff, %esi       # imm = 0x3FFFFFFF
movl (%rdx,%rax), %edi
andl %ecx, %edi
orl %esi, %edi
movl %edi, (%rdx,%rax)
addq $0x1c, %rax
jmp 0x18b555
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq