// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/gfa_ut.cpp
// Function: integer_chain(unsigned int, integer_aln_t*, long, long, integer_t*, ma_ug_t*, ul_str_idx_t*, all_ul_t*, ul_chain_t*)
uint32_t integer_chain(uint32_t qid, integer_aln_t *a, int64_t a_n, int64_t offset, integer_t *buf, 
ma_ug_t *ug, ul_str_idx_t *str_idx, all_ul_t *ul_idx, ul_chain_t *res)
{
    res->v = res->s = res->e = (uint32_t)-1; res->sc = (uint64_t)-1; 
    res->q_sidx = res->q_eidx = res->t_sidx = res->t_eidx = (uint32_t)-1;
    if(a_n <= 0) return 0;
    ///already sorted by qe
    int64_t i, k, max_f, max_k, sc, csc, *p, *f, tf, ti/**, is_circle**/;
    integer_aln_t *li, *lk; uint32_t tid = a[0].tn_rev_qk>>33; uint32_t is_rev = (a[0].tn_rev_qk>>32)&1;
    for (i = 1, sc = 0; i < a_n; ++i) {
        sc += a[i].sc;
        if(a[i].tk <= a[i-1].tk) break;///== means there is a circle
        if(((uint32_t)a[i].tn_rev_qk) <= ((uint32_t)a[i-1].tn_rev_qk)) break;
        if(str_idx && ul_idx && (!dis_check_integer_aln_t(ul_idx, str_idx, 
                                    ug, &(a[i]), &(a[i-1]), qid, tid, is_rev, 0.08, 2000))) {
            break;
        }
    }
    // if(tid == 269 || tid == 276 || tid == 277 || tid == 278) fprintf(stderr, "tid->%u, i->%ld, an->%ld\n", tid, i, a_n);
    if(i >= a_n) {//the whole chain is co-inear
        sc += a[0].sc; 
        res->v = a[0].tn_rev_qk>>32; res->s = offset; res->e = offset + a_n; res->sc = sc; 
        return 1;
    }
    // is_circle = 1;
    // if(str_idx->str.a[qid].is_cir == 0 && str_idx->str.a[tid].is_cir == 0) is_circle = 0;

    buf->p.n = buf->f.n = 0;
    kv_resize(int64_t, buf->p, (uint64_t)a_n); p = buf->p.a;
    kv_resize(int64_t, buf->f, (uint64_t)a_n); f = buf->f.a;

    tf = ti = -1;
    for (i = 0; i < a_n; ++i) {
        li = &(a[i]); csc = a[i].sc;
        max_f = csc; max_k = -1;
        for (k = i-1; k >= 0; --k) { 
            lk = &(a[k]);
            ///qk of lk and li might be equal
            if(lk->tk >= li->tk || ((uint32_t)lk->tn_rev_qk) >= ((uint32_t)li->tn_rev_qk)) continue;
            // if(is_circle && (!dis_check_integer_aln_t(ul_idx, str_idx, ug, li, lk, qid, tid, is_rev, 0.08))) continue;
            if(str_idx && ul_idx && (!dis_check_integer_aln_t(ul_idx, str_idx, 
                                                    ug, li, lk, qid, tid, is_rev, 0.08, 2000))) {
                continue;
            }
            sc = csc + f[k];
            if(sc > max_f) {
                max_f = sc; max_k = k;
            }
        }
        f[i] = max_f; p[i] = max_k;
        if(tf < max_f) {
            tf = max_f; ti = i;
        }
    }

    if(ti < 0) return 0;
    
    for (i = ti, k = 0; i >= 0; i = p[i]) f[k++] = i;
    assert(k > 0);
    for (i = sc = 0, k--; k >= 0; k--, i++) {
        a[i] = a[f[k]]; sc += a[i].sc;
        // if(tid == 269) {
        //     fprintf(stderr, "[%ld] qk->%u, tk->%u\n", i, (uint32_t)a[i].tn_rev_qk, a[i].tk);
        // }
    }
    res->v = a[0].tn_rev_qk>>32; res->s = offset; res->e = offset + i; res->sc = sc;
    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r9, 0x38(%rsp)
movq %rdx, %rbx
movl %edi, 0xc(%rsp)
movq 0xc0(%rsp), %rdx
movq $-0x1, %rax
movq %rax, (%rdx)
movl $0xffffffff, 0x8(%rdx)  # imm = 0xFFFFFFFF
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x10(%rdx)
movq %rax, 0x20(%rdx)
testq %rbx, %rbx
jle 0x1f4781
movq 0xb0(%rsp), %rdx
movq 0x10(%rsi), %rax
movq %rax, %rdi
shrq $0x21, %rdi
movq %rdi, 0x28(%rsp)
shrq $0x20, %rax
andl $0x1, %eax
movq %rax, 0x30(%rsp)
cmpq $0x1, %rbx
setne %bpl
movq %rsi, 0x10(%rsp)
movq %rcx, 0x20(%rsp)
movq %r8, 0x18(%rsp)
je 0x1f44b8
testq %rdx, %rdx
setne %dil
cmpq $0x0, 0xb8(%rsp)
setne %al
movl 0x18(%rsi), %ecx
movl 0x20(%rsi), %r14d
cmpl (%rsi), %ecx
jbe 0x1f44bb
andb %al, %dil
movl $0x2, %r13d
movq %rsi, %r12
movb %dil, 0xb(%rsp)
movl 0x28(%r12), %eax
cmpl 0x10(%r12), %eax
jbe 0x1f44bb
leaq 0x18(%r12), %r15
testb %dil, %dil
je 0x1f448f
subq $0x8, %rsp
movq 0xc0(%rsp), %rdi
movq %rdx, %rsi
movq 0x40(%rsp), %rdx
movq %r15, %rcx
movq %r12, %r8
movl 0x14(%rsp), %r9d
movq 0x310a0(%rip), %xmm0    # 0x225508
pushq $0x7d0                  # imm = 0x7D0
pushq 0x40(%rsp)
pushq 0x40(%rsp)
callq 0x1f4138
movb 0x2b(%rsp), %dil
movq 0xd0(%rsp), %rdx
addq $0x20, %rsp
testl %eax, %eax
je 0x1f44bb
cmpq %rbx, %r13
setl %bpl
je 0x1f44bb
movl 0x30(%r12), %eax
movl 0x38(%r12), %esi
addq %rsi, %r14
incq %r13
cmpl 0x18(%r12), %eax
movq %r15, %r12
ja 0x1f4427
jmp 0x1f44bb
xorl %r14d, %r14d
testb $0x1, %bpl
je 0x1f4785
xorl %eax, %eax
movq 0x18(%rsp), %r14
movq %rax, 0x48(%r14)
movq %rax, 0x60(%r14)
cmpq %rbx, 0x68(%r14)
movq 0x10(%rsp), %r12
jae 0x1f4531
leaq -0x1(%rbx), %rax
movq %rax, %rcx
shrq %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x2, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x4, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x8, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x10, %rcx
orq %rax, %rcx
leaq 0x1(%rcx), %rax
movq %rax, 0x68(%r14)
movq 0x70(%r14), %rdi
leaq 0x8(,%rcx,8), %rsi
callq 0x2370
movq %rax, 0x70(%r14)
movq 0x70(%r14), %r13
cmpq %rbx, 0x50(%r14)
jae 0x1f458d
leaq -0x1(%rbx), %rax
movq %rax, %rcx
shrq %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x2, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x4, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x8, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x10, %rcx
orq %rax, %rcx
leaq 0x1(%rcx), %rax
movq %rax, 0x50(%r14)
movq 0x58(%r14), %rdi
leaq 0x8(,%rcx,8), %rsi
callq 0x2370
movq %rax, 0x58(%r14)
movq 0x58(%r14), %r15
movq 0xb0(%rsp), %rsi
testq %rsi, %rsi
setne %al
cmpq $0x0, 0xb8(%rsp)
setne %dl
andb %al, %dl
cmpq $0x2, %rbx
movl $0x1, %eax
cmovgeq %rbx, %rax
movq %rax, 0x40(%rsp)
leaq -0x18(%r12), %rdi
movq $-0x1, %r14
xorl %r9d, %r9d
movq $-0x1, %rcx
movq $-0x1, %rax
movq %r13, 0x48(%rsp)
movb %dl, 0xb(%rsp)
movq %rax, 0x50(%rsp)
movq %rcx, 0x70(%rsp)
leaq (%r9,%r9,2), %rax
movl 0x8(%r12,%rax,8), %ecx
movq %r9, 0x58(%rsp)
testq %r9, %r9
movq %rdi, 0x68(%rsp)
movq %r14, 0x60(%rsp)
je 0x1f46b7
leaq (%r12,%rax,8), %rbx
movq $-0x1, %r13
movq %rdi, %r12
movq %rcx, %rbp
movq %rcx, 0x18(%rsp)
movl (%r12), %eax
cmpl (%rbx), %eax
jae 0x1f469d
movl 0x10(%r12), %eax
cmpl 0x10(%rbx), %eax
jae 0x1f469d
testb %dl, %dl
je 0x1f468b
subq $0x8, %rsp
movq 0xc0(%rsp), %rdi
movq 0x40(%rsp), %rdx
movq %rbx, %rcx
movq %r12, %r8
movl 0x14(%rsp), %r9d
movq 0x30ea8(%rip), %xmm0    # 0x225508
pushq $0x7d0                  # imm = 0x7D0
pushq 0x40(%rsp)
pushq 0x40(%rsp)
callq 0x1f4138
movq 0x38(%rsp), %rcx
movb 0x2b(%rsp), %dl
movq 0xd0(%rsp), %rsi
addq $0x20, %rsp
testl %eax, %eax
je 0x1f469d
movq (%r15,%r14,8), %rax
addq %rcx, %rax
cmpq %rbp, %rax
cmovgq %r14, %r13
cmovgq %rax, %rbp
leaq -0x1(%r14), %rax
incq %r14
addq $-0x18, %r12
cmpq $0x1, %r14
movq %rax, %r14
jg 0x1f4626
jmp 0x1f46c1
movq $-0x1, %r13
movq %rcx, %rbp
movq 0x58(%rsp), %r9
movq %rbp, (%r15,%r9,8)
movq 0x48(%rsp), %rax
movq %r13, (%rax,%r9,8)
movq %rax, %r13
movq 0x50(%rsp), %rax
cmpq %rbp, %rax
cmovleq %rbp, %rax
movq 0x70(%rsp), %rcx
cmovlq %r9, %rcx
incq %r9
movq 0x60(%rsp), %r14
incq %r14
movq 0x68(%rsp), %rdi
addq $0x18, %rdi
cmpq 0x40(%rsp), %r9
movq 0x10(%rsp), %r12
jne 0x1f45e5
testq %rcx, %rcx
js 0x1f4781
movl $0x1, %eax
movq %rcx, -0x8(%r15,%rax,8)
movq (%r13,%rcx,8), %rcx
incq %rax
testq %rcx, %rcx
jns 0x1f4719
leaq 0x8(%r12), %rcx
xorl %r14d, %r14d
movq 0x20(%rsp), %rdi
movq %rdi, %rbx
movq 0xc0(%rsp), %rsi
movq -0x10(%r15,%rax,8), %rdx
leaq (%rdx,%rdx,2), %rdx
movdqu (%r12,%rdx,8), %xmm0
movdqu %xmm0, -0x8(%rcx)
movq 0x10(%r12,%rdx,8), %rdx
movq %rdx, 0x8(%rcx)
movl (%rcx), %edx
addq %rdx, %r14
addq $0x18, %rcx
incq %rbx
decq %rax
cmpq $0x1, %rax
jg 0x1f4743
movl 0x14(%r12), %eax
movl %eax, 0x8(%rsi)
movl %edi, (%rsi)
jmp 0x1f47a8
xorl %eax, %eax
jmp 0x1f47b4
movq 0x10(%rsp), %rcx
movl 0x8(%rcx), %eax
movl 0x14(%rcx), %ecx
addq %rax, %r14
movq 0xc0(%rsp), %rsi
movl %ecx, 0x8(%rsi)
movq 0x20(%rsp), %rax
movl %eax, (%rsi)
addq %rax, %rbx
movl %ebx, 0x4(%rsi)
movq %r14, 0x10(%rsi)
movl $0x1, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq