// File: chhylp123[P]hifiasm/Overlaps.cpp
// Function: bi_paration(asg_t*, unsigned long*, unsigned int)
void bi_paration(asg_t *bi_g, uint64_t* array, uint32_t bi_graph_Len)
{
    
    kvec_t(uint64_t) a;
    kv_init(a);
    a.a = array;
    a.n = a.m = bi_g->n_seq;
    kdq_t(uint32_t) *buf;
    buf = kdq_init(uint32_t);
    uint32_t i, len, v, w, k, nv, roundID = 0;
    asg_arc_t *av;
    for (i = 0; i < bi_g->n_seq; i++)
    {
        bi_g->seq[i].c = 0;
    }

    re_partition:

    for (i = 0; i < bi_g->n_seq; i++)
    {
        /****************************may have bugs********************************/
        ///how many reads contained in this contig
        len = (a.a[i]>>33);
        /****************************may have bugs********************************/
        ///if the contig is too small, or the contig has already been visited
        ///if(len < bi_graph_Len || bi_g->seq[i].len != UNVISIT) continue;
        if(len < bi_graph_Len || bi_g->seq[i].c == 1) continue;
        if(roundID == 0 && bi_g->seq[i].len == UNVISIT) continue;

        ///set the color of this node
        bi_g->seq[i].len = RED; bi_g->seq[i].c = 1;
        kdq_push(uint32_t, buf, i);
        while (kdq_size(buf) != 0)
        {
            v = *(kdq_pop(uint32_t, buf)); bi_g->seq[v].c = 1;
            if(bi_g->seq[v].len == ISO) continue;
            nv = asg_arc_n(bi_g, v);
            av = asg_arc_a(bi_g, v);


            ///get all out-nodes of v
            for(k = 0; k < nv; k++)
            {
                w = av[k].v;
                /****************************may have bugs********************************/
                ///if(bi_g->seq[w].len == bi_g->seq[v].len)
                len = (a.a[w]>>33);
                ///only check large contig
                if(len >= bi_graph_Len && bi_g->seq[w].len == bi_g->seq[v].len)
                { /****************************may have bugs********************************/
                    break;
                }
            }
            ///means v is conflict 
            if(k != nv)
            {
                bi_g->seq[v].len = ISO; bi_g->seq[v].c = 1;
                continue;
            }



            ///if v is not conflict with others
            for(k = 0; k < nv; k++)
            {
                w = av[k].v;
                ///if the out-node has not been visited
                if(bi_g->seq[w].len == UNVISIT)
                {
                    bi_g->seq[w].len = 1 - bi_g->seq[v].len;
                    bi_g->seq[w].c = 1;
                    /****************************may have bugs********************************/
                    len = (a.a[w]>>33);
                    /****************************may have bugs********************************/
                    if(len < bi_graph_Len) continue;
                    kdq_push(uint32_t, buf, w);
                }
                ///here bi_g->seq[w].len might be ISO or another color
                ///don't need to do anything here
            }
        }
    }

    if(roundID == 0)
    {
        roundID = 1;
        goto re_partition;
    }
    

    //secondary checking
    // uint32_t a_color;
    // kdq_size(buf) = 0;
    // for (i = 0; i < bi_g->n_seq; i++)
    // {
    //     /****************************may have bugs********************************/
    //     len = (a.a[i]>>33);
    //     /****************************may have bugs********************************/
    //     ///just check end contig
    //     if(bi_g->seq[i].len != UNVISIT || (a.a[i] & (uint64_t)(0x100000000)) == 0) continue;
        
    //     v = i;
    //     nv = asg_arc_n(bi_g, v);
    //     av = asg_arc_a(bi_g, v);
    //     a_color = UNVISIT;

    //     for(k = 0; k < nv; k++)
    //     {
    //         w = av[k].v;
    //         ///check all out-nodes that has already been colored
    //         if(bi_g->seq[w].len != UNVISIT)
    //         {
    //             ///if this is the first colored node
    //             if(a_color == UNVISIT)
    //             {
    //                 a_color = bi_g->seq[w].len;
    //             }///if this is not
    //             else if(a_color != bi_g->seq[w].len)
    //             {
    //                 a_color = ISO;
    //                 bi_g->seq[v].len = ISO;
    //                 break;
    //             }
    //         }
    //     }

    //     if(a_color == ISO) continue;
    //     ///no colored out-node
    //     if(a_color == UNVISIT)
    //     {
    //         bi_g->seq[v].len = RED;
    //     }
    //     else
    //     {
    //         bi_g->seq[v].len = 1 - a_color;
    //     }



        

    //     ///check if all reachable nodes are end-contig
    //     kdq_push(uint32_t, buf, i);
    //     while (kdq_size(buf) != 0)
    //     {
    //         v = *(kdq_pop(uint32_t, buf));
    //         ///find a non-end contig
    //         if((a.a[v] & (uint64_t)(0x100000000)) == 0)
    //         {
    //             bi_g->seq[i].len = UNVISIT;
    //             kdq_size(buf) = 0;
    //             break;
    //         }

    //         nv = asg_arc_n(bi_g, v);
    //         av = asg_arc_a(bi_g, v);
    //         for(k = 0; k < nv; k++)
    //         {
    //             w = av[k].v;
    //             ///if the out-node has not been visited
    //             if(bi_g->seq[w].len == UNVISIT)
    //             {
    //                 bi_g->seq[v].len = LABLE;
    //                 kdq_push(uint32_t, buf, w);
    //             }
    //         }
    //     }

    //     for (v = 0; v < bi_g->n_seq; v++)
    //     {
    //         if(bi_g->seq[v].len == LABLE) bi_g->seq[v].len = UNVISIT;
    //     }

    //     if(bi_g->seq[i].len == UNVISIT)
    //     {
    //         continue;
    //     }






    //     ///now all reachable nodes of i are end-contigs
    //     kdq_push(uint32_t, buf, i);
    //     while (kdq_size(buf) != 0)
    //     {
    //         ///each v here is the uncolored node in the first round
    //         v = *(kdq_pop(uint32_t, buf));
    //         if(bi_g->seq[v].len == ISO) continue;
    //         nv = asg_arc_n(bi_g, v);
    //         av = asg_arc_a(bi_g, v);


    //         ///get all out-nodes of v
    //         for(k = 0; k < nv; k++)
    //         {
    //             w = av[k].v;
    //             if(bi_g->seq[w].len == bi_g->seq[v].len)
    //             {
    //                 break;
    //             }
    //         }
    //         ///means v is conflict 
    //         if(k != nv)
    //         {
    //             bi_g->seq[v].len = ISO;
    //             continue;
    //         }



    //         ///if v is not conflict with others
    //         for(k = 0; k < nv; k++)
    //         {
    //             w = av[k].v;
    //             ///if the out-node has not been visited
    //             if(bi_g->seq[w].len == UNVISIT)
    //             {   
    //                 bi_g->seq[w].len = 1 - bi_g->seq[v].len;
    //                 kdq_push(uint32_t, buf, w);
    //             }
    //         }
    //     }
    // }

    kdq_destroy(uint32_t, buf);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %eax, %eax
movq %rax, -0x28(%rbp)
movq %rax, -0x30(%rbp)
callq 0x1412a0
movq %rax, -0x38(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq -0x8(%rbp), %rcx
movl 0x14(%rcx), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
jae 0x1430af
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x3c(%rbp), %ecx
movb $0x0, 0x4(%rax,%rcx,8)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x143080
jmp 0x1430b1
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq -0x8(%rbp), %rcx
movl 0x14(%rcx), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
jae 0x143363
movq -0x20(%rbp), %rax
movl -0x3c(%rbp), %ecx
movq (%rax,%rcx,8), %rax
shrq $0x21, %rax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x14(%rbp), %eax
jb 0x1430ff
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x3c(%rbp), %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0x1, %eax
jne 0x143104
jmp 0x143355
cmpl $0x0, -0x54(%rbp)
jne 0x143129
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x3c(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
jne 0x143129
jmp 0x143355
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x3c(%rbp), %ecx
movl (%rax,%rcx,8), %edx
andl $0x80000000, %edx       # imm = 0x80000000
orl $0x0, %edx
movl %edx, (%rax,%rcx,8)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x3c(%rbp), %ecx
movb $0x1, 0x4(%rax,%rcx,8)
movq -0x38(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0x141380
movq -0x38(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x143353
movq -0x38(%rbp), %rdi
callq 0x141410
movl (%rax), %eax
movl %eax, -0x44(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movb $0x1, 0x4(%rax,%rcx,8)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x2, %eax
jne 0x1431a6
jmp 0x14315f
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movl -0x44(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x28(%rcx), %rcx
movl -0x44(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x50(%rbp), %eax
jae 0x143255
movq -0x60(%rbp), %rax
movl -0x4c(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0x48(%rbp)
movq -0x20(%rbp), %rax
movl -0x48(%rbp), %ecx
movq (%rax,%rcx,8), %rax
shrq $0x21, %rax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x14(%rbp), %eax
jb 0x143248
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq -0x8(%rbp), %rcx
movq 0x20(%rcx), %rcx
movl -0x44(%rbp), %edx
movl (%rcx,%rdx,8), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
jne 0x143248
jmp 0x143255
jmp 0x14324a
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1431e5
movl -0x4c(%rbp), %eax
cmpl -0x50(%rbp), %eax
je 0x14328c
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movl (%rax,%rcx,8), %edx
andl $0x80000000, %edx       # imm = 0x80000000
orl $0x2, %edx
movl %edx, (%rax,%rcx,8)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movb $0x1, 0x4(%rax,%rcx,8)
jmp 0x14315f
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x50(%rbp), %eax
jae 0x14334e
movq -0x60(%rbp), %rax
movl -0x4c(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
jne 0x14333e
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x44(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl $0x1, %esi
subl %eax, %esi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
movl (%rax,%rcx,8), %edx
andl $0x7fffffff, %esi       # imm = 0x7FFFFFFF
andl $0x80000000, %edx       # imm = 0x80000000
orl %esi, %edx
movl %edx, (%rax,%rcx,8)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x48(%rbp), %ecx
movb $0x1, 0x4(%rax,%rcx,8)
movq -0x20(%rbp), %rax
movl -0x48(%rbp), %ecx
movq (%rax,%rcx,8), %rax
shrq $0x21, %rax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x143332
jmp 0x143340
movq -0x38(%rbp), %rdi
movl -0x48(%rbp), %esi
callq 0x141380
jmp 0x143340
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x143293
jmp 0x14315f
jmp 0x143355
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x1430b8
cmpl $0x0, -0x54(%rbp)
jne 0x143375
movl $0x1, -0x54(%rbp)
jmp 0x1430b1
movq -0x38(%rbp), %rdi
callq 0x141340
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)