// File: chhylp123[P]hifiasm/Overlaps.cpp
// Function: collect_abnormal_edges(ma_hit_t_alloc*, ma_hit_t_alloc*, long long)
void collect_abnormal_edges(ma_hit_t_alloc* paf, ma_hit_t_alloc* rev_paf, long long readNum)
{
    double startTime = Get_T();
    long long T_edges, T_Single_Dir_Edges_0, T_Single_Dir_Edges_1, T_Conflict_Equal_Edges, T_Conflict_Strong_Edges;
    T_edges = T_Single_Dir_Edges_0 = T_Single_Dir_Edges_1 = T_Conflict_Equal_Edges = T_Conflict_Strong_Edges = 0;
    long long T_Single_Dir_Edges_1_1000 = 0;
    long long related_reads = 0;
    long long related_overlaps = 0;
    long long i, j;
    uint32_t qn, tn;
    int is_equal_f, is_strong_f; 
    int is_equal_b, is_strong_b, is_exist_b; 

    kvec_t(uint64_t) edge_vector;
    kv_init(edge_vector);
    
    for (i = 0; i < readNum; i++)
    {
        for (j = 0; j < (long long)paf[i].length; j++)
        {
            qn = Get_qn(paf[i].buffer[j]);
            tn = Get_tn(paf[i].buffer[j]);
            T_edges++;

            is_equal_f = paf[i].buffer[j].el;
            is_strong_f = paf[i].buffer[j].ml;
            
            is_exist_b = get_specific_overlap(&(paf[tn]), tn, qn);
            if(is_exist_b == -1)
            {
                is_exist_b = get_specific_overlap(&(rev_paf[tn]), tn, qn);
                if(is_exist_b != -1)
                {
                    T_Single_Dir_Edges_0++;
                    kv_push(uint64_t, edge_vector, qn);
                    kv_push(uint64_t, edge_vector, tn);
                    ///related_overlaps += paf[qn].length + rev_paf[qn].length + paf[tn].length + rev_paf[tn].length;
                    // fprintf(stderr, "%.*s(%d) ---(+)--> %.*s(%d), Len: %d\n", 
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // Get_qe(paf[i].buffer[j]) - Get_qs(paf[i].buffer[j]));

                    // fprintf(stderr, "%.*s(%d) ---(-)--> %.*s(%d), Len: %d\n\n", 
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // Get_qe(rev_paf[tn].buffer[is_exist_b]) - Get_qs(rev_paf[tn].buffer[is_exist_b]));
                } 
                else
                {
                    T_Single_Dir_Edges_1++;
                    if(Get_qe(paf[i].buffer[j]) - Get_qs(paf[i].buffer[j]) >= 1000)
                    {
                        T_Single_Dir_Edges_1_1000++;
                        // fprintf(stderr, "%.*s(%d) ---(%d)--> %.*s(%d), Len: %d\n\n", 
                        // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                        // is_strong_f,
                        // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                        // Get_qe(paf[i].buffer[j]) - Get_qs(paf[i].buffer[j]));
                    }
                }

                related_reads = related_reads + 2;
            }
            else
            {
                is_equal_b = paf[tn].buffer[is_exist_b].el;
                is_strong_b = paf[tn].buffer[is_exist_b].ml;

                if(is_equal_f != is_equal_b)
                {
                    T_Conflict_Equal_Edges++;

                    // fprintf(stderr, "%.*s(%d) ---(%d)--> %.*s(%d), Len: %d\n", 
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // is_equal_f,
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // Get_qe(paf[i].buffer[j]) - Get_qs(paf[i].buffer[j]));

                    // fprintf(stderr, "%.*s(%d) ---(%d)--> %.*s(%d), Len: %d\n\n", 
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // is_equal_b,
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // Get_qe(paf[tn].buffer[is_exist_b]) - Get_qs(paf[tn].buffer[is_exist_b]));
                } 
                
                if(is_strong_f != is_strong_b)
                {
                    T_Conflict_Strong_Edges++;
                    // fprintf(stderr, "%.*s(%d) ---(%d)--> %.*s(%d), Len: %d\n", 
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // is_strong_f,
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // Get_qe(paf[i].buffer[j]) - Get_qs(paf[i].buffer[j]));

                    // fprintf(stderr, "%.*s(%d) ---(%d)--> %.*s(%d), Len: %d\n\n", 
                    // Get_NAME_LENGTH(R_INF, tn), Get_NAME(R_INF, tn), tn,
                    // is_strong_b,
                    // Get_NAME_LENGTH(R_INF, qn), Get_NAME(R_INF, qn), qn,
                    // Get_qe(paf[tn].buffer[is_exist_b]) - Get_qs(paf[tn].buffer[is_exist_b]));
                } 

                if(is_equal_f != is_equal_b || is_strong_f != is_strong_b)
                {
                    related_reads++;
                }
            }
        }
    }

    radix_sort_arch64(edge_vector.a, edge_vector.a + edge_vector.n);
    uint64_t pre = (uint64_t)-1;
    long long mn = 0;
    for (i = 0; i < (long long)edge_vector.n; i++)
    {
        if(pre != edge_vector.a[i])
        {
            mn++;
            pre = edge_vector.a[i];
            related_overlaps += paf[pre].length + rev_paf[pre].length;
        }

        if(i>0 && edge_vector.a[i] < edge_vector.a[i-1]) fprintf(stderr, "hehe\n");
    }
    
    

    fprintf(stderr, "****************statistic for abnormal overlaps****************\n");
    fprintf(stderr, "overlaps #: %lld\n", T_edges);
	fprintf(stderr, "one direction overlaps (different phasing)#: %lld\n", T_Single_Dir_Edges_0);
    fprintf(stderr, "one direction overlaps (missing)#: %lld\n", T_Single_Dir_Edges_1);
    fprintf(stderr, "one direction overlaps (missing) >= 1000#: %lld\n", T_Single_Dir_Edges_1_1000);
    fprintf(stderr, "conflict strong/weak overlaps #: %lld\n", T_Conflict_Strong_Edges);
    fprintf(stderr, "conflict exact/inexact overlaps #: %lld\n", T_Conflict_Equal_Edges);
    fprintf(stderr, "related_reads #: %lld/%lld\n", related_reads, mn);
    fprintf(stderr, "related_overlaps #: %lld\n", related_overlaps);
    fprintf(stderr, "****************statistic for abnormal overlaps****************\n");

    fprintf(stderr, "[M::%s] took %0.2fs\n\n", __func__, Get_T()-startTime);

    kv_destroy(edge_vector);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
callq 0x2510
movsd %xmm0, -0x20(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
movq $0x0, -0x98(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x18(%rbp), %rax
jge 0x14fbe4
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x8(%rbp), %rcx
imulq $0x18, -0x68(%rbp), %rdx
addq %rdx, %rcx
movl 0xc(%rcx), %ecx
cmpq %rcx, %rax
jge 0x14fbd1
movq -0x8(%rbp), %rax
imulq $0x18, -0x68(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x70(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
shrq $0x20, %rax
movl %eax, -0x74(%rbp)
movq -0x8(%rbp), %rax
imulq $0x18, -0x68(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x70(%rbp), %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movl %eax, -0x78(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
imulq $0x18, -0x68(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x70(%rbp), %rcx
addq %rcx, %rax
movzbl 0x20(%rax), %eax
movl %eax, -0x7c(%rbp)
movq -0x8(%rbp), %rax
imulq $0x18, -0x68(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x70(%rbp), %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
shrq $0x1e, %rax
andq $0x1, %rax
movl %eax, -0x80(%rbp)
movq -0x8(%rbp), %rdi
movl -0x78(%rbp), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
movl -0x78(%rbp), %esi
movl -0x74(%rbp), %edx
callq 0xce1b0
movl %eax, -0x8c(%rbp)
cmpl $-0x1, -0x8c(%rbp)
jne 0x14fb12
movq -0x10(%rbp), %rdi
movl -0x78(%rbp), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
movl -0x78(%rbp), %esi
movl -0x74(%rbp), %edx
callq 0xce1b0
movl %eax, -0x8c(%rbp)
cmpl $-0x1, -0x8c(%rbp)
je 0x14faaa
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jne 0x14f9f5
cmpq $0x0, -0xa0(%rbp)
je 0x14f9bb
movq -0xa0(%rbp), %rax
shlq %rax
movq %rax, -0xc0(%rbp)
jmp 0x14f9c9
movl $0x2, %eax
movq %rax, -0xc0(%rbp)
jmp 0x14f9c9
movq -0xc0(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rdi
movq -0xa0(%rbp), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, -0x98(%rbp)
movl -0x74(%rbp), %eax
movl %eax, %edx
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xa8(%rbp)
movq %rdx, (%rax,%rcx,8)
jmp 0x14fa1c
movq -0xa8(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jne 0x14fa83
cmpq $0x0, -0xa0(%rbp)
je 0x14fa49
movq -0xa0(%rbp), %rax
shlq %rax
movq %rax, -0xc8(%rbp)
jmp 0x14fa57
movl $0x2, %eax
movq %rax, -0xc8(%rbp)
jmp 0x14fa57
movq -0xc8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rdi
movq -0xa0(%rbp), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, -0x98(%rbp)
movl -0x78(%rbp), %eax
movl %eax, %edx
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xa8(%rbp)
movq %rdx, (%rax,%rcx,8)
jmp 0x14fb01
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
imulq $0x18, -0x68(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x70(%rbp), %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movq -0x8(%rbp), %rcx
imulq $0x18, -0x68(%rbp), %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
imulq $0x28, -0x70(%rbp), %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
subl %ecx, %eax
cmpl $0x3e8, %eax            # imm = 0x3E8
jb 0x14faff
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x14fb01
movq -0x58(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x58(%rbp)
jmp 0x14fbbe
movq -0x8(%rbp), %rax
movl -0x78(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq -0x8c(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movzbl 0x20(%rax), %eax
movl %eax, -0x84(%rbp)
movq -0x8(%rbp), %rax
movl -0x78(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq -0x8c(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
shrq $0x1e, %rax
andq $0x1, %rax
movl %eax, -0x88(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x84(%rbp), %eax
je 0x14fb83
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movl -0x80(%rbp), %eax
cmpl -0x88(%rbp), %eax
je 0x14fb9a
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x84(%rbp), %eax
jne 0x14fbb0
movl -0x80(%rbp), %eax
cmpl -0x88(%rbp), %eax
je 0x14fbbc
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x14fbbe
jmp 0x14fbc0
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x14f880
jmp 0x14fbd3
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x14f86a
movq -0x98(%rbp), %rdi
movq -0x98(%rbp), %rsi
movq -0xa8(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
callq 0xc90e0
movq $-0x1, -0xb0(%rbp)
movq $0x0, -0xb8(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jge 0x14fcf8
movq -0xb0(%rbp), %rax
movq -0x98(%rbp), %rcx
movq -0x68(%rbp), %rdx
cmpq (%rcx,%rdx,8), %rax
je 0x14fca2
movq -0xb8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
movq -0x98(%rbp), %rax
movq -0x68(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xb0(%rbp)
movq -0x8(%rbp), %rax
imulq $0x18, -0xb0(%rbp), %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movq -0x10(%rbp), %rcx
imulq $0x18, -0xb0(%rbp), %rdx
addq %rdx, %rcx
addl 0xc(%rcx), %eax
movl %eax, %eax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x68(%rbp)
jle 0x14fce5
movq -0x98(%rbp), %rax
movq -0x68(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x98(%rbp), %rcx
movq -0x68(%rbp), %rdx
subq $0x1, %rdx
cmpq (%rcx,%rdx,8), %rax
jae 0x14fce5
movq 0x27430c(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x2395a5(%rip), %rsi    # 0x389283
movb $0x0, %al
callq 0x22a0
jmp 0x14fce7
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x14fc23
movq 0x2742e1(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x239af6(%rip), %rsi    # 0x3897ff
movb $0x0, %al
callq 0x22a0
movq 0x2742c9(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x28(%rbp), %rdx
leaq 0x239bbd(%rip), %rsi    # 0x3898e2
movb $0x0, %al
callq 0x22a0
movq 0x2742ad(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x30(%rbp), %rdx
leaq 0x239aff(%rip), %rsi    # 0x389840
movb $0x0, %al
callq 0x22a0
movq 0x274291(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x38(%rbp), %rdx
leaq 0x239b16(%rip), %rsi    # 0x389873
movb $0x0, %al
callq 0x22a0
movq 0x274275(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x50(%rbp), %rdx
leaq 0x239b23(%rip), %rsi    # 0x38989c
movb $0x0, %al
callq 0x22a0
movq 0x274259(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x48(%rbp), %rdx
leaq 0x239b38(%rip), %rsi    # 0x3898cd
movb $0x0, %al
callq 0x22a0
movq 0x27423d(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x40(%rbp), %rdx
leaq 0x239b43(%rip), %rsi    # 0x3898f4
movb $0x0, %al
callq 0x22a0
movq 0x274221(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x58(%rbp), %rdx
movq -0xb8(%rbp), %rcx
leaq 0x239b49(%rip), %rsi    # 0x38991d
movb $0x0, %al
callq 0x22a0
movq 0x2741fe(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x60(%rbp), %rdx
leaq 0x239b49(%rip), %rsi    # 0x389939
movb $0x0, %al
callq 0x22a0
movq 0x2741e2(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x2399f7(%rip), %rsi    # 0x3897ff
movb $0x0, %al
callq 0x22a0
movq 0x2741ca(%rip), %rax    # 0x3c3fe0
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
callq 0x2510
movq -0xd0(%rbp), %rdi
subsd -0x20(%rbp), %xmm0
leaq 0x239b1b(%rip), %rsi    # 0x389953
leaq 0x239b2a(%rip), %rdx    # 0x389969
movb $0x1, %al
callq 0x22a0
movq -0x98(%rbp), %rdi
callq 0x2210
addq $0xd0, %rsp
popq %rbp
retq
nopl (%rax,%rax)