// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/Overlaps.cpp
// Function: get_ref_nid_flank(u_trans_t*, ma_ug_t*, ma_ug_t*, ma_ug_t*, scaf_res_t*, scaf_res_t*, unsigned long, unsigned long, unsigned long, asg32_v*)
uint64_t get_ref_nid_flank(u_trans_t *z, ma_ug_t *ref, ma_ug_t *hu1, ma_ug_t *hu2, scaf_res_t *cp1, scaf_res_t *cp2, uint64_t is_beg, uint64_t gap_bd, uint64_t flank_len, asg32_v *res)
{
    scaf_res_t *sc = NULL; uint64_t id, s_end, e_end, rn = res->n;
    if(z->tn < hu1->u.n) {
        sc = cp1; id = z->tn;
    } else {
        sc = cp2; id = z->tn - hu1->u.n;
    }

    if(is_beg) {
        s_end = 0; e_end = 1;
    } else {
        s_end = 1; e_end = 0;
    }

    if(z->rev) {
        s_end ^= 1; e_end ^= 1;
    }


    ul_vec_t *idx = &(sc->a[id]); uint64_t k, m, a_n, os, oe, m0; 
    uc_block_t *a, *am = NULL; uint64_t max_len = 0, cgap, clen; int64_t ami, amn = 0, as, ae, amz; 
    // if(z->tn == 5) {
    //     fprintf(stderr, "\n[M::%s] h1tg%.6u%c(%c)\ts::%u\te::%u\ts_end::%lu\te_end::%lu\n", __func__, z->tn+1, "lc"[hu1->u.a[z->tn].circ], "+-"[z->rev], z->ts, z->te, s_end, e_end);
    // }
    
    for (k = 0; k < idx->bb.n; k++) {
        a = idx->bb.a + idx->bb.a[k].ts; a_n = idx->bb.a[k].te - idx->bb.a[k].ts;
        os = MAX(z->ts, idx->bb.a[k].qs); 
        oe = MIN(z->te, idx->bb.a[k].qe);
        // if(z->tn == 5) {
        //     fprintf(stderr, "[M::%s] idx->bb.a[%lu]::[%u, %u), o[%lu, %lu), a_n::%lu\n", __func__, k, idx->bb.a[k].qs, idx->bb.a[k].qe, os, oe, a_n);
        // }
        if(os >= oe) continue;
        for(m = 0; m < a_n && a[m].qe <= os; m++); 
        // {
            // if(z->tn == 5) fprintf(stderr, "+(%lu)utg%.6u%c[%u,%u),", m, (a[m].hid)+1, "lc"[ref->u.a[a[m].hid].circ], a[m].qs, a[m].qe);
        // }
        // if(z->tn == 5) fprintf(stderr, "\n[M::%s] +m::%lu\n", __func__, m);
        if(m >= a_n) continue;
        for(m0 = m; m < a_n && a[m].qs < oe; m++); 
        // {
            // if(z->tn == 5) fprintf(stderr, "-(%lu)utg%.6u%c[%u,%u),", m, (a[m].hid)+1, "lc"[ref->u.a[a[m].hid].circ], a[m].qs, a[m].qe);
        // }
        // if(z->tn == 5) fprintf(stderr, "\n[M::%s] -m::%lu\n", __func__, m);
        if(m <= m0) continue;

        os = MAX(z->ts, a[m0].qs); 
        oe = MIN(z->te, a[m-1].qe);
        // if(z->tn == 5) {
        //     fprintf(stderr, "[M::%s] m0::%lu, m::%lu, o[%lu, %lu), a_n::%lu\n", __func__, m0, m, os, oe, a_n);
        // }
        if(oe <= os) continue;
        clen = oe - os; cgap = 0;
        if(s_end) {
            cgap = os - z->ts;
        } else if(e_end) {
            cgap = z->te - oe;
        }
        if(cgap > gap_bd) continue;
        if(clen > max_len) {
            max_len = clen; am = a + m0; amn = m - m0;
        }
    }

    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-0-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tamn::%ld\ts_end::%lu\te_end::%lu\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, amn, s_end, e_end);
    // }

    // if(z->tn == 5) fprintf(stderr, "[M::%s] amn::%ld\n", __func__, amn);

    if((!am) || (!amn)) return 0;
    os = oe = 0; as = 0; ae = amn;
    if(s_end) {
        for(ami = 0; (ami < amn) && ((z->ts + flank_len) >= am[ami].qe); ami++);
        if((ami < amn) && ((z->ts + flank_len) >= am[ami].qs)) ami++;
        as = 0; ae = ami;
    } else if(e_end) {
        for(ami = amn - 1; (ami >= 0) && (z->te <= (am[ami].qs + flank_len)); ami--);
        if((ami >= 0) && (z->te <= (am[ami].qe + flank_len))) ami--;
        ami++; as = ami; ae = amn;
    }
    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-1-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tas::%ld\tae::%ld\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, as, ae);
    // }
    // if(z->tn == 5) fprintf(stderr, "+[M::%s] as::%ld, ae::%ld\n", __func__, as, ae);
    if(as >= ae) return 0;
    
    ///make sure there are no identical node
    if(s_end) {
        for (ami = as; ami < ae; ami++) {
            for (amz = ami + 1; (amz < ae) && (am[ami].hid != am[amz].hid); amz++);
            if(amz < ae) {
                ae = ami + 1; break;
            }
        }
    } else if(e_end) {
        for (ami = ae - 1; ami >= as; ami--) {
            for (amz = ami - 1; (amz >= as) && (am[ami].hid != am[amz].hid); amz--);
            if(amz >= as) {
                as = ami; break;
            }
        }
    }
    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-1-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tas::%ld\tae::%ld\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, as, ae);
    // }
    // if(z->tn == 5) fprintf(stderr, "+[M::%s] as::%ld, ae::%ld\n", __func__, as, ae);
    if(as >= ae) return 0;

    uint32_t *fp = NULL, r2n = 0;
    kv_resize(uint32_t, *res, rn + ((ae - as)<<1));
    for (ami = as; ami < ae; ami++) {
        m = ((uint64_t)(am[ami].hid<<1))|((uint64_t)(!!(am[ami].rev))); m ^= ((uint64_t)(!!(z->rev)));
        kv_push(uint32_t, *res, m);
    }
    rn = res->n - rn;
    if(z->rev) {
        fp = res->a + res->n - rn; r2n = rn>>1;
        for (k = 0; k < r2n; k++) {
            m = fp[k]; fp[k] = fp[rn - k -1]; fp[rn - k -1] = m;
        }
    }

    if(s_end) {
        for (ami = as; ami < ae; ami++) {
            m = ((am[ami].qs>=z->ts)?(am[ami].qs-z->ts):(0));
            kv_push(uint32_t, *res, m);
        }
    } else if(e_end) {
        for (ami = as; ami < ae; ami++) {
            m = ((z->te>=am[ami].qe)?(z->te-am[ami].qe):(0));
            kv_push(uint32_t, *res, m);
        }
    }
    if(z->rev) {
        fp = res->a + res->n - rn; r2n = rn>>1;
        for (k = 0; k < r2n; k++) {
            m = fp[k]; fp[k] = fp[rn - k - 1]; fp[rn - k - 1] = m;
        }
    }
    
    return rn;
    // return ((uint64_t)(am->hid<<1))|((uint64_t)(!!(am->rev))); 
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl 0x14(%rdi), %eax
movq (%rdx), %rcx
xorl %edx, %edx
cmpq %rax, %rcx
cmovaq %rdx, %rcx
cmovbeq %r9, %r8
subq %rcx, %rax
cmpq $0x0, 0x70(%rsp)
setne 0xd(%rsp)
sete 0xe(%rsp)
movb 0x28(%rdi), %cl
andb $0x40, %cl
shrb $0x6, %cl
movb %cl, 0xf(%rsp)
movq (%r8), %rcx
imulq $0x58, %rax, %rdx
movq 0x20(%rcx,%rdx), %rax
testq %rax, %rax
movq %rdi, 0x20(%rsp)
je 0xdb732
addq %rdx, %rcx
addq $0x20, %rcx
movq 0x10(%rcx), %rdx
movl 0xc(%rdi), %esi
movl 0x10(%rdi), %edi
leaq 0x2c(%rdx), %r8
leaq 0x4(%rdx), %rcx
movq %rcx, 0x30(%rsp)
movq $0x0, 0x18(%rsp)
movq $0x0, 0x28(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r10d, %r10d
leaq (%r10,%r10,8), %r9
movl 0x4(%rdx,%r9,4), %ecx
movl 0x8(%rdx,%r9,4), %ebp
cmpl %ecx, %esi
cmoval %esi, %ecx
cmpl %ebp, %edi
cmovbl %edi, %ebp
cmpl %ebp, %ecx
jae 0xdb724
movl 0xc(%rdx,%r9,4), %r11d
movl 0x10(%rdx,%r9,4), %r13d
cmpl %r11d, %r13d
setne %r15b
je 0xdb724
leaq (%r11,%r11,8), %r9
leaq (%rdx,%r9,4), %r14
subl %r11d, %r13d
cmpq $0x1, %r13
movq %r13, %rbx
adcq $0x0, %rbx
cmpl %ecx, 0x8(%r14)
jbe 0xdb649
xorl %r11d, %r11d
jmp 0xdb672
leaq (%r8,%r9,4), %r15
decq %rbx
xorl %r11d, %r11d
cmpq %r11, %rbx
je 0xdb724
leaq 0x24(%r15), %r12
incq %r11
cmpl %ecx, (%r15)
movq %r12, %r15
jbe 0xdb653
cmpq %r13, %r11
setb %r15b
testb %r15b, %r15b
je 0xdb724
leaq (%r11,%r11,8), %rcx
movq %r11, %r12
cmpq %r13, %r11
jae 0xdb6ab
shlq $0x2, %r9
leaq (%r9,%rcx,4), %r9
addq 0x30(%rsp), %r9
movq %r11, %r12
cmpl %ebp, (%r9)
jae 0xdb6ab
incq %r12
addq $0x24, %r9
cmpq %r13, %r12
jb 0xdb697
movq %r13, %r12
movq %r12, %r9
subq %r11, %r9
jbe 0xdb724
movl 0x4(%r14,%rcx,4), %ebx
cmpl %ebx, %esi
cmoval %esi, %ebx
leaq (%r12,%r12,8), %r11
movl -0x1c(%r14,%r11,4), %r11d
cmpl %r11d, %edi
cmovbl %edi, %r11d
cmpl %ebx, %r11d
jbe 0xdb724
movl %r11d, %r11d
movl %ebx, %ebx
movq %rbx, %r15
subq %rsi, %r15
movq %rdi, %r12
subq %r11, %r12
movb 0xf(%rsp), %bpl
cmpb 0xd(%rsp), %bpl
movl $0x0, %r13d
cmovneq %r12, %r13
cmpb 0xe(%rsp), %bpl
cmovneq %r15, %r13
cmpq 0x78(%rsp), %r13
ja 0xdb724
subq %rbx, %r11
cmpq 0x28(%rsp), %r11
jbe 0xdb724
leaq (%r14,%rcx,4), %rcx
movq %rcx, 0x10(%rsp)
movq %r11, 0x28(%rsp)
movq %r9, 0x18(%rsp)
incq %r10
cmpq %rax, %r10
jne 0xdb5f1
jmp 0xdb744
movq $0x0, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r14d, %r14d
cmpq $0x0, 0x10(%rsp)
je 0xdbb19
movq 0x18(%rsp), %r10
testq %r10, %r10
je 0xdbb19
movq 0x80(%rsp), %rax
movb 0xf(%rsp), %r8b
cmpb 0xe(%rsp), %r8b
jne 0xdb788
cmpb 0xd(%rsp), %r8b
movq 0x20(%rsp), %r9
jne 0xdb7be
xorl %ebx, %ebx
jmp 0xdb822
testq %r10, %r10
movq 0x20(%rsp), %r9
jle 0xdb809
movl 0xc(%r9), %ecx
addq %rax, %rcx
movq 0x10(%rsp), %rax
leaq 0x8(%rax), %rdx
xorl %ebx, %ebx
xorl %eax, %eax
movl (%rdx), %esi
cmpq %rsi, %rcx
jb 0xdb810
decq %rax
addq $0x24, %rdx
movq %r10, %rsi
addq %rax, %rsi
jne 0xdb7a6
jmp 0xdb822
movq %r10, %rbx
sarq $0x3f, %rbx
andq %r10, %rbx
leaq (%r10,%r10,8), %rcx
movq 0x10(%rsp), %rdx
leaq (%rdx,%rcx,4), %rdx
addq $0x8, %rdx
movq %r10, %rcx
testq %rcx, %rcx
jle 0xdb822
decq %rcx
movl 0x10(%r9), %esi
movl -0x28(%rdx), %edi
addq %rax, %rdi
addq $-0x24, %rdx
cmpq %rsi, %rdi
jae 0xdb7dc
movl (%rdx), %edx
addq %rax, %rdx
leaq 0x1(%rcx), %rbx
cmpq %rsi, %rdx
cmovaeq %rcx, %rbx
jmp 0xdb822
xorl %ebx, %ebx
xorl %r10d, %r10d
jmp 0xdb822
movl -0x4(%rdx), %edx
cmpq %rdx, %rcx
adcq $-0x1, %rax
negq %rax
xorl %ebx, %ebx
movq %rax, %r10
cmpq %r10, %rbx
jge 0xdbb16
cmpb 0xe(%rsp), %r8b
jne 0xdb89d
cmpb 0xd(%rsp), %r8b
je 0xdb8f6
cmpq %rbx, %r10
jle 0xdb8f6
leaq -0x1(%r10), %rax
leaq (%r10,%r10,8), %rcx
movq 0x10(%rsp), %rdx
leaq (%rdx,%rcx,4), %rcx
addq $-0x48, %rcx
movq %r10, %rdx
movq %rdx, %rsi
decq %rdx
addq $-0x2, %rsi
cmpq %rbx, %rsi
jl 0xdb88f
leaq (%rdx,%rdx,8), %rsi
movq 0x10(%rsp), %rdi
movl (%rdi,%rsi,4), %esi
movq %rcx, %rdi
movq %rax, %r8
cmpl (%rdi), %esi
je 0xdb8f3
decq %r8
addq $-0x24, %rdi
cmpq %rbx, %r8
jg 0xdb87f
decq %rax
addq $-0x24, %rcx
cmpq %rbx, %rdx
jg 0xdb85e
jmp 0xdb8f6
cmpq %r10, %rbx
jge 0xdb8f6
leaq (%rbx,%rbx,8), %rax
movq 0x10(%rsp), %rcx
leaq (%rcx,%rax,4), %rax
addq $0x24, %rax
movq %rbx, %rcx
movq %rcx, %rdx
incq %rcx
cmpq %r10, %rcx
jge 0xdb8e3
leaq (%rdx,%rdx,8), %rdx
movq 0x10(%rsp), %rsi
movl (%rsi,%rdx,4), %edx
movq %rax, %rsi
movq %rcx, %rdi
cmpl (%rsi), %edx
je 0xdb8ee
incq %rdi
addq $0x24, %rsi
cmpq %r10, %rdi
jl 0xdb8d3
addq $0x24, %rax
cmpq %r10, %rcx
jne 0xdb8b6
jmp 0xdb8f6
movq %rcx, %r10
jmp 0xdb8f6
movq %rdx, %rbx
movq %r10, %rax
subq %rbx, %rax
jle 0xdbb16
movq 0x88(%rsp), %rbp
movq (%rbp), %rcx
movq %rcx, 0x28(%rsp)
leaq (%rcx,%rax,2), %rax
cmpq %rax, 0x8(%rbp)
movq %r10, 0x18(%rsp)
jae 0xdb97d
decq %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, 0x8(%rbp)
movq 0x10(%rbp), %rdi
leaq 0x4(,%rcx,4), %rsi
callq 0x2370
movq 0x18(%rsp), %r10
movq 0x20(%rsp), %r9
movq %rax, 0x10(%rbp)
movq %r10, %r14
movq %rbx, 0x30(%rsp)
subq %rbx, %r14
jle 0xdba1e
movq 0x30(%rsp), %rax
leaq (%rax,%rax,8), %rax
movq 0x10(%rsp), %rcx
leaq (%rcx,%rax,4), %r12
addq $0x20, %r12
movl -0x20(%r12), %ebx
movl (%r12), %r15d
movl 0x28(%r9), %r13d
movq 0x8(%rbp), %rax
cmpq %rax, (%rbp)
jne 0xdb9ea
leaq (%rax,%rax), %rsi
testq %rax, %rax
movl $0x2, %eax
cmoveq %rax, %rsi
movq %rsi, 0x8(%rbp)
movq 0x10(%rbp), %rdi
shlq $0x2, %rsi
callq 0x2370
movq 0x18(%rsp), %r10
movq 0x20(%rsp), %r9
movq %rax, 0x10(%rbp)
shrl $0x5, %r15d
andl $0x1, %r15d
leal (%r15,%rbx,2), %eax
shrl $0x6, %r13d
andl $0x1, %r13d
xorl %eax, %r13d
movq (%rbp), %rax
movq 0x10(%rbp), %rcx
leaq 0x1(%rax), %rdx
movq %rdx, (%rbp)
movl %r13d, (%rcx,%rax,4)
addq $0x24, %r12
decq %r14
jne 0xdb9a4
movq (%rbp), %r11
movq %r11, %r14
movq 0x28(%rsp), %r15
subq %r15, %r14
testb $0x40, 0x28(%r9)
je 0xdba6e
movq %r14, %rcx
shrq %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
andq %rcx, %rax
je 0xdba6e
movq 0x10(%rbp), %rdx
leaq (%rdx,%r15,4), %rcx
leaq (%rdx,%r11,4), %rdx
addq $-0x4, %rdx
xorl %esi, %esi
movl (%rcx,%rsi,4), %edi
movl (%rdx), %r8d
movl %r8d, (%rcx,%rsi,4)
movl %edi, (%rdx)
incq %rsi
addq $-0x4, %rdx
cmpq %rsi, %rax
jne 0xdba56
movq %r11, 0x18(%rsp)
movb 0xf(%rsp), %al
cmpb 0xe(%rsp), %al
movq 0x30(%rsp), %rcx
jne 0xdbb2b
cmpb 0xd(%rsp), %al
je 0xdbba8
subq %rcx, %r10
jle 0xdbba8
leaq (%rcx,%rcx,8), %rax
movq 0x10(%rsp), %rcx
leaq (%rcx,%rax,4), %r12
addq $0x8, %r12
xorl %esi, %esi
movl 0x10(%r9), %r13d
subl (%r12), %r13d
cmovbl %esi, %r13d
movq 0x8(%rbp), %rax
cmpq %rax, (%rbp)
jne 0xdbaf4
leaq (%rax,%rax), %rsi
testq %rax, %rax
movl $0x2, %eax
cmoveq %rax, %rsi
movq %rsi, 0x8(%rbp)
movq 0x10(%rbp), %rdi
shlq $0x2, %rsi
movq %r10, %rbx
callq 0x2370
xorl %esi, %esi
movq %rbx, %r10
movq 0x20(%rsp), %r9
movq %rax, 0x10(%rbp)
movq (%rbp), %rax
movq 0x10(%rbp), %rcx
leaq 0x1(%rax), %rdx
movq %rdx, (%rbp)
movl %r13d, (%rcx,%rax,4)
addq $0x24, %r12
decq %r10
jne 0xdbaac
jmp 0xdbba8
xorl %r14d, %r14d
movq %r14, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
subq %rcx, %r10
jle 0xdbba8
leaq (%rcx,%rcx,8), %rax
movq 0x10(%rsp), %rcx
leaq (%rcx,%rax,4), %r12
addq $0x4, %r12
xorl %esi, %esi
movl (%r12), %r13d
subl 0xc(%r9), %r13d
cmovbl %esi, %r13d
movq 0x8(%rbp), %rax
cmpq %rax, (%rbp)
jne 0xdbb8b
leaq (%rax,%rax), %rsi
testq %rax, %rax
movl $0x2, %eax
cmoveq %rax, %rsi
movq %rsi, 0x8(%rbp)
movq 0x10(%rbp), %rdi
shlq $0x2, %rsi
movq %r10, %rbx
callq 0x2370
xorl %esi, %esi
movq %rbx, %r10
movq 0x20(%rsp), %r9
movq %rax, 0x10(%rbp)
movq (%rbp), %rax
movq 0x10(%rbp), %rcx
leaq 0x1(%rax), %rdx
movq %rdx, (%rbp)
movl %r13d, (%rcx,%rax,4)
addq $0x24, %r12
decq %r10
jne 0xdbb43
testb $0x40, 0x28(%r9)
je 0xdbb19
movq %r14, %rcx
shrq %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
andq %rcx, %rax
je 0xdbb19
movq (%rbp), %rdx
movq 0x10(%rbp), %rsi
shlq $0x2, %r15
leaq (%r15,%rdx,4), %rcx
movq 0x18(%rsp), %rdi
shlq $0x2, %rdi
subq %rdi, %rcx
addq %rsi, %rcx
leaq (%rsi,%rdx,4), %rdx
addq $-0x4, %rdx
xorl %esi, %esi
movl (%rcx,%rsi,4), %edi
movl (%rdx), %r8d
movl %r8d, (%rcx,%rsi,4)
movl %edi, (%rdx)
incq %rsi
addq $-0x4, %rdx
cmpq %rsi, %rax
jne 0xdbbf0
jmp 0xdbb19