// File: /workspace/github_cpp_makefile_star2_O3/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), %ecx
movq (%rdx), %rax
xorl %r14d, %r14d
cmpq %rcx, %rax
cmovaq %r14, %rax
cmovbeq %r9, %r8
subq %rax, %rcx
cmpq $0x0, 0x70(%rsp)
setne 0x5(%rsp)
sete 0x6(%rsp)
movq (%r8), %rax
imulq $0x58, %rcx, %rdx
movq 0x20(%rax,%rdx), %rcx
testq %rcx, %rcx
je 0xdcdf5
movq 0x88(%rsp), %rsi
movq (%rsi), %rsi
movq %rsi, 0x28(%rsp)
movb 0x28(%rdi), %sil
shrb $0x6, %sil
andb $0x1, %sil
movb %sil, 0x7(%rsp)
addq %rdx, %rax
addq $0x20, %rax
movq 0x10(%rax), %rsi
movl 0xc(%rdi), %r12d
movq %rdi, 0x18(%rsp)
movl 0x10(%rdi), %r8d
leaq 0x4(%rsi), %r9
xorl %edi, %edi
movq $0x0, 0x10(%rsp)
movq $0x0, 0x8(%rsp)
xorl %r10d, %r10d
leaq (%r10,%r10,8), %rax
movl 0x4(%rsi,%rax,4), %r11d
movl 0x8(%rsi,%rax,4), %r13d
cmpl %r11d, %r12d
cmoval %r12d, %r11d
cmpl %r13d, %r8d
cmovbl %r8d, %r13d
cmpl %r13d, %r11d
jae 0xdcaa9
movl 0xc(%rsi,%rax,4), %edx
movl 0x10(%rsi,%rax,4), %eax
cmpl %edx, %eax
je 0xdcaa9
leaq (%rdx,%rdx,8), %r14
subl %edx, %eax
cmpq $0x1, %rax
movq %rax, %rbx
adcq $0x0, %rbx
leaq (%rsi,%r14,4), %rdx
leaq (%r9,%r14,4), %r15
movq %rdx, %r14
xorl %ebp, %ebp
cmpl %r11d, 0x8(%r14)
ja 0xdca16
incq %rbp
addq $0x24, %r14
addq $0x24, %r15
cmpq %rbp, %rbx
jne 0xdc9fb
jmp 0xdcaa9
movq %rbp, %r11
cmpq %rax, %rbp
jae 0xdcaa9
cmpl %r13d, (%r15)
jae 0xdca36
incq %r11
addq $0x24, %r15
cmpq %rax, %r11
jb 0xdca22
movq %rax, %r11
movq %r11, %rax
subq %rbp, %rax
jbe 0xdcaa9
movl 0x4(%r14), %ebx
cmpl %ebx, %r12d
cmoval %r12d, %ebx
leaq (%r11,%r11,8), %r11
movl -0x1c(%rdx,%r11,4), %edx
cmpl %edx, %r8d
cmovbl %r8d, %edx
cmpl %ebx, %edx
jbe 0xdcaa9
movl %edx, %edx
movl %ebx, %r11d
movq %r11, %rbx
subq %r12, %rbx
movq %r8, %r15
subq %rdx, %r15
movb 0x7(%rsp), %bpl
cmpb 0x5(%rsp), %bpl
movl $0x0, %r13d
cmovneq %r15, %r13
cmpb 0x6(%rsp), %bpl
cmovneq %rbx, %r13
cmpq 0x78(%rsp), %r13
ja 0xdcaa9
subq %r11, %rdx
cmpq 0x10(%rsp), %rdx
jbe 0xdcaa9
movq %r14, 0x8(%rsp)
movq %rdx, 0x10(%rsp)
movq %rax, %rdi
incq %r10
cmpq %rcx, %r10
jne 0xdc9a8
xorl %r14d, %r14d
cmpq $0x0, 0x8(%rsp)
je 0xdcdf5
movq %rdi, %r9
testq %rdi, %rdi
movq 0x18(%rsp), %r10
movq 0x88(%rsp), %r12
movb 0x7(%rsp), %dil
je 0xdcdf5
cmpb 0x6(%rsp), %dil
jne 0xdcb0e
cmpb 0x5(%rsp), %dil
movq 0x80(%rsp), %r8
jne 0xdcb4b
xorl %ebx, %ebx
movl $0x0, %r14d
testq %r9, %r9
jg 0xdcc6e
jmp 0xdcdf5
testq %r9, %r9
movq 0x80(%rsp), %rcx
jle 0xdcdf2
movl 0xc(%r10), %eax
addq %rcx, %rax
movq 0x8(%rsp), %rcx
leaq 0x8(%rcx), %rdx
xorl %ebx, %ebx
xorl %ecx, %ecx
movl (%rdx), %esi
cmpq %rsi, %rax
jb 0xdcb96
decq %rcx
addq $0x24, %rdx
movq %r9, %rsi
addq %rcx, %rsi
jne 0xdcb33
jmp 0xdcba8
movq %r9, %rbx
sarq $0x3f, %rbx
andq %r9, %rbx
leaq (%r9,%r9,8), %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,4), %rcx
addq $0x8, %rcx
movq %r9, %rax
testq %rax, %rax
jle 0xdcba8
decq %rax
movl 0x10(%r10), %edx
movl -0x28(%rcx), %esi
addq %r8, %rsi
addq $-0x24, %rcx
cmpq %rdx, %rsi
jae 0xdcb69
movl (%rcx), %ecx
addq %r8, %rcx
leaq 0x1(%rax), %rbx
cmpq %rdx, %rcx
cmovaeq %rax, %rbx
jmp 0xdcba8
movl -0x4(%rdx), %edx
cmpq %rdx, %rax
adcq $-0x1, %rcx
negq %rcx
xorl %ebx, %ebx
movq %rcx, %r9
cmpq %r9, %rbx
jge 0xdcdf2
cmpb 0x6(%rsp), %dil
jne 0xdcc1a
cmpb 0x5(%rsp), %dil
je 0xdcc6e
leaq -0x1(%r9), %rax
leaq (%r9,%r9,8), %rcx
movq 0x8(%rsp), %rdx
leaq (%rdx,%rcx,4), %rcx
addq $-0x48, %rcx
movq %r9, %rdx
movq %rdx, %rsi
decq %rdx
addq $-0x2, %rsi
cmpq %rbx, %rsi
jl 0xdcc0c
leaq (%rdx,%rdx,8), %rsi
movq 0x8(%rsp), %rdi
movl (%rdi,%rsi,4), %esi
movq %rcx, %rdi
movq %rax, %r8
cmpl (%rdi), %esi
je 0xdcc6b
decq %r8
addq $-0x24, %rdi
cmpq %rbx, %r8
jg 0xdcbfc
decq %rax
addq $-0x24, %rcx
cmpq %rbx, %rdx
jg 0xdcbdb
jmp 0xdcc6e
leaq (%rbx,%rbx,8), %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,4), %rax
addq $0x24, %rax
movq %rbx, %rcx
movq %rcx, %rdx
incq %rcx
cmpq %r9, %rcx
jge 0xdcc5b
leaq (%rdx,%rdx,8), %rdx
movq 0x8(%rsp), %rsi
movl (%rsi,%rdx,4), %edx
movq %rax, %rsi
movq %rcx, %rdi
cmpl (%rsi), %edx
je 0xdcc66
incq %rdi
addq $0x24, %rsi
cmpq %r9, %rdi
jl 0xdcc4b
addq $0x24, %rax
cmpq %r9, %rcx
jne 0xdcc2e
jmp 0xdcc6e
movq %rcx, %r9
jmp 0xdcc6e
movq %rdx, %rbx
movq %r9, %r14
subq %rbx, %r14
jle 0xdcdf2
movq %r9, 0x10(%rsp)
movq 0x28(%rsp), %rax
leaq (%rax,%r14,2), %rax
cmpq %rax, 0x8(%r12)
jae 0xdcce8
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(%r12)
movq 0x10(%r12), %rdi
leaq 0x4(,%rcx,4), %rsi
callq 0x2370
movq 0x18(%rsp), %r10
movq %rax, 0x10(%r12)
movq (%r12), %rcx
movq 0x10(%r12), %rax
movq %rbx, 0x30(%rsp)
leaq (%rbx,%rbx,8), %rsi
movq 0x8(%rsp), %rdx
movq %rsi, 0x20(%rsp)
leaq (%rdx,%rsi,4), %r13
addq $0x20, %r13
movl -0x20(%r13), %r15d
movl (%r13), %ebx
movl 0x28(%r10), %ebp
cmpq 0x8(%r12), %rcx
jne 0xdcd50
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r12)
shlq $0x2, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x18(%rsp), %r10
movq %rax, 0x10(%r12)
movq (%r12), %rdx
jmp 0xdcd53
movq %rcx, %rdx
shrl $0x5, %ebx
andl $0x1, %ebx
leal (%rbx,%r15,2), %ecx
shrl $0x6, %ebp
andl $0x1, %ebp
xorl %ecx, %ebp
leaq 0x1(%rdx), %rcx
movq %rcx, (%r12)
movl %ebp, (%rax,%rdx,4)
addq $0x24, %r13
decq %r14
jne 0xdcd0c
movq %rcx, %r14
subq 0x28(%rsp), %r14
testb $0x40, 0x28(%r10)
je 0xdcdcc
movq %r14, %rsi
shrq %rsi
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
andq %rsi, %rax
je 0xdcdcc
movq 0x10(%r12), %rdi
leaq (%rdi,%rcx,4), %rsi
leaq (,%r14,4), %r8
subq %r8, %rsi
leaq (%rdi,%rdx,4), %rdx
xorl %edi, %edi
movl (%rsi,%rdi,4), %r8d
movl (%rdx), %r9d
movl %r9d, (%rsi,%rdi,4)
movl %r8d, (%rdx)
incq %rdi
addq $-0x4, %rdx
cmpq %rdi, %rax
jne 0xdcdb2
movb 0x7(%rsp), %al
cmpb 0x6(%rsp), %al
movq 0x30(%rsp), %rdx
jne 0xdce07
cmpb 0x5(%rsp), %al
movq 0x10(%rsp), %r8
jne 0xdce88
movq %rcx, %rdx
jmp 0xdcf02
xorl %r14d, %r14d
movq %r14, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x10(%r12), %rax
movq 0x10(%rsp), %r8
subq %rdx, %r8
movq 0x8(%rsp), %rdx
movq 0x20(%rsp), %rsi
leaq (%rdx,%rsi,4), %r13
addq $0x4, %r13
xorl %ebp, %ebp
movl (%r13), %ebx
subl 0xc(%r10), %ebx
cmovbl %ebp, %ebx
cmpq 0x8(%r12), %rcx
jne 0xdce6f
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r12)
shlq $0x2, %rsi
movq %rax, %rdi
movq %r8, %r15
callq 0x2370
movq %r15, %r8
movq 0x18(%rsp), %r10
movq %rax, 0x10(%r12)
movq (%r12), %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, (%r12)
movl %ebx, (%rax,%rcx,4)
addq $0x24, %r13
movq %rdx, %rcx
decq %r8
jne 0xdce28
jmp 0xdcf02
movq 0x10(%r12), %rax
subq %rdx, %r8
movq 0x8(%rsp), %rdx
movq 0x20(%rsp), %rsi
leaq (%rdx,%rsi,4), %r13
addq $0x8, %r13
xorl %ebp, %ebp
movl 0x10(%r10), %ebx
subl (%r13), %ebx
cmovbl %ebp, %ebx
cmpq 0x8(%r12), %rcx
jne 0xdceeb
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r12)
shlq $0x2, %rsi
movq %rax, %rdi
movq %r8, %r15
callq 0x2370
movq %r15, %r8
movq 0x18(%rsp), %r10
movq %rax, 0x10(%r12)
movq (%r12), %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, (%r12)
movl %ebx, (%rax,%rcx,4)
addq $0x24, %r13
movq %rdx, %rcx
decq %r8
jne 0xdcea4
testb $0x40, 0x28(%r10)
je 0xdcdf5
movq %r14, %rcx
shrq %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
andq %rcx, %rax
je 0xdcdf5
movq 0x10(%r12), %rsi
leaq (%rsi,%rdx,4), %rcx
leaq (,%r14,4), %rdi
subq %rdi, %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 0xdcf3f
jmp 0xdcdf5