// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Purge_Dups.cpp
// Function: get_read_peak(asg_t*, long long*, long long, long long*, long long*, long long*, long long*, long long*, long long)
void get_read_peak(asg_t *read_g, long long* cov_buf, long long cov_buf_length, long long* topo_peak_cov, 
long long* hom_peak, long long* het_peak, long long* k_mer_only, long long* coverage_only, long long g_size)
{
    long long i, start, err_i, max_i, max2_i, max3_i, topo_peak_i, max, max2, max3, topo_peak, min;

    i = start = err_i = max_i = max2_i = max3_i = topo_peak_i = -1;
    max = max2 = max3 = topo_peak = min = -1;

    ///cov_buf[0] is usually very large
    for (i = 1; i < cov_buf_length; ++i)
    {
        if(cov_buf[i] > cov_buf[i-1]) break;
    }
    err_i = i - 1;
    // find the global highest peak
	max_i = err_i + 1, max = cov_buf[max_i];
    for (i = max_i; i < cov_buf_length; ++i)
    {
        if (cov_buf[i] > max)
        {
            max = cov_buf[i];
            max_i = i;
        }
    }

    ///print_peak(cov_buf, cov_buf_length, max_i);

    // look for smaller peak on the low end
	max2 = -1; max2_i = -1;
	for (i = max_i - 1; i > err_i; --i) 
    {
		///at first, it should be a peak
		if (cov_buf[i] >= cov_buf[i-1] && cov_buf[i] >= cov_buf[i+1]) 
        {
			if (cov_buf[i] > max2)
            {
                max2 = cov_buf[i];
                max2_i = i;
            } 
		}
	}

    ///fprintf(stderr, "***max2: %lld, max2_i: %lld\n", max2, max2_i);

    if (max2_i != -1 && max2_i > err_i && max2_i < max_i) 
    {
		for (i = max2_i + 1, min = max; i < max_i; ++i)
        {
            if (cov_buf[i] < min) min = cov_buf[i];
        }
			
		///if the second peak is not significant
		if(max2 < max * 0.05 || min > max2 * 0.95) max2 = max2_i = -1;
	}
    if(max2 < max*0.0075) max2 = max2_i = -1;
		

    // look for smaller peak on the high end
	max3 = -1; max3_i = -1;
    // we'd better use i < cov_buf_length - 1, since cov_buf[cov_buf_length-1] may have problem
	for (i = max_i + 1; i < cov_buf_length - 1; ++i) 
    {
		//at first, it should be a peak
		if (cov_buf[i] >= cov_buf[i-1] && cov_buf[i] >= cov_buf[i+1]) 
        {
			if (cov_buf[i] > max3)
            {
                max3 = cov_buf[i], max3_i = i;
            } 
		}
	}

    ///fprintf(stderr, "***max3: %lld, max3_i: %lld\n", max3, max3_i);
    
    //if found a peak
	if (max3 != -1 && max3_i > max_i) 
    {
		for (i = max_i + 1, min = max; i < max3_i; ++i)
        {
            if (cov_buf[i] < min) min = cov_buf[i];
        }
			
		if (max3 < max * 0.05 || min > max3 * 0.95 || max3_i > max_i * 3) max3 = max3_i = -1;
	}
    if (max3 < max*0.0075) max3 = max3_i = -1;

    

    (*hom_peak) = (*het_peak) = -1;
    if (topo_peak_cov && (*topo_peak_cov) < cov_buf_length)
    {
        topo_peak_i = (*topo_peak_cov);
        topo_peak = cov_buf[topo_peak_i];
        if (topo_peak <= max * 0.05) topo_peak_i = topo_peak = -1;
    }

    if(asm_opt.purge_level_primary == 0) 
    {
        (*hom_peak) = max_i;
        return;
    }
    
    
    long long k_mer_het, k_mer_hom, coverage_het, coverage_hom, alter_peak;
    k_mer_het = k_mer_hom = coverage_het = coverage_hom = alter_peak = -1;

    alter_peak = topo_peak_i;
    k_mer_het = asm_opt.het_cov;
    k_mer_hom = asm_opt.hom_cov;
    if(max3_i > 0)
    {
        coverage_het = max_i;
        coverage_hom = max3_i;
    }
    else
    {
        coverage_het = max2_i;
        coverage_hom = max_i;
    }

    if(g_size > 0) {
        long long n_bs, m_peak_hom = -1;
        int p_ht = -1;
        for (i = n_bs = 0; i < read_g->n_seq; i++) n_bs += read_g->seq[i].len;
        m_peak_hom = n_bs/g_size;
        if(m_peak_hom > 0) {
            p_ht = -1;
            coverage_hom = adj_m_peak_hom(m_peak_hom, max_i, max2_i, max3_i, &p_ht);
            coverage_het = p_ht;
        }   
    }

    if(k_mer_het != -1)
    {
        (*het_peak) = k_mer_het;
        (*hom_peak) = k_mer_hom;
        return;
    }
    else if(coverage_het != -1)
    {
        (*het_peak) = coverage_het;
        (*hom_peak) = coverage_hom;
        return;
    }
    else if(k_mer_hom > coverage_hom*1.5)
    {
        (*het_peak) = coverage_hom;
        (*hom_peak) = k_mer_hom;
        return;
    }
    else if(alter_peak != -1)
    {
        ///if peak is het, coverage peak is more reliable 
        if(coverage_hom >= alter_peak*0.8 && coverage_hom <= alter_peak*1.2) 
        {
            (*het_peak) = coverage_hom;
            return;
        }///if peak is homo, k-mer peak is more reliable 
        else if(k_mer_hom >= alter_peak*0.8*2 && k_mer_hom <= alter_peak*1.2*2)
        {
            (*hom_peak) = k_mer_hom;
            return;
        }
    }

    (*k_mer_only) = k_mer_hom;
    (*coverage_only) = coverage_hom;
    

    // fprintf(stderr, "max: %lld, max_i: %lld\n", max, max_i);
    // fprintf(stderr, "max2: %lld, max2_i: %lld\n", max2, max2_i);
    // fprintf(stderr, "max3: %lld, max3_i: %lld\n", max3, max3_i);
    // fprintf(stderr, "[M::%s] Heterozygous k-mer peak: %d\n", __func__, asm_opt.het_cov);
    // fprintf(stderr, "[M::%s] Homozygous k-mer peak: %d\n", __func__, asm_opt.hom_cov);
    // fprintf(stderr, "[M::%s] Heterozygous coverage peak: %lld\n", __func__, (*het_peak));
    // fprintf(stderr, "[M::%s] Homozygous coverage peak: %lld\n", __func__, (*hom_peak));
    // fprintf(stderr, "[M::%s] Alter coverage peak: %lld\n", __func__, topo_peak_i);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %r15
movq %rsi, %rax
movq %rdi, 0x10(%rsp)
movl $0x1, %r11d
cmpq $0x2, %rdx
movq %r8, 0x18(%rsp)
jl 0x109793
movq (%rax,%r11,8), %rcx
cmpq -0x8(%rax,%r11,8), %rcx
jg 0x109793
incq %r11
cmpq %r11, %rdx
jne 0x10976d
movq (%rax,%rdx,8), %r10
movq $-0x1, %r13
movq %rdx, %rsi
jmp 0x10989a
movq (%rax,%r11,8), %r10
movq $-0x1, %r13
cmpq %rdx, %r11
jge 0x109897
movq %r11, %rsi
movq %r11, %rdi
movq (%rax,%rdi,8), %rcx
cmpq %r10, %rcx
cmovgq %rdi, %rsi
cmovgq %rcx, %r10
incq %rdi
cmpq %rdi, %rdx
jne 0x1097ad
cmpq %r11, %rsi
jle 0x10989a
movq %r15, %r8
movq %r9, %rbx
movq $-0x1, %rdi
movq $-0x1, %r13
movq %rsi, %r14
leaq -0x1(%r14), %r15
movq -0x8(%rax,%r14,8), %r12
cmpq -0x10(%rax,%r14,8), %r12
jl 0x109816
cmpq (%rax,%r14,8), %r12
setge %cl
cmpq %rdi, %r12
setg %bpl
movq %r15, %r14
testb %bpl, %cl
jne 0x109810
movq %r13, %r14
movq %rdi, %r12
movq %r14, %r13
movq %r12, %rdi
movq %r15, %r14
cmpq %r11, %r15
jg 0x1097e4
cmpq $-0x1, %r13
je 0x109b15
cmpq %r11, %r13
movq %rbx, %r9
movq %r8, %r15
jl 0x1098a1
cmpq %rsi, %r13
jge 0x1098a1
leaq 0x1(%r13), %r15
movq %r10, %r11
cmpq %rsi, %r15
jge 0x10985a
movq %r10, %r11
movq (%rax,%r15,8), %rcx
cmpq %r11, %rcx
cmovlq %rcx, %r11
incq %r15
cmpq %r15, %rsi
jne 0x109847
cvtsi2sd %rdi, %xmm0
cvtsi2sd %r10, %xmm1
mulsd 0x127d5c(%rip), %xmm1   # 0x2315c8
ucomisd %xmm0, %xmm1
movq %rbx, %r9
movq %r8, %r15
ja 0x10988e
xorps %xmm1, %xmm1
cvtsi2sd %r11, %xmm1
mulsd 0x127d10(%rip), %xmm0   # 0x231598
ucomisd %xmm0, %xmm1
jbe 0x1098a1
movq $-0x1, %r13
jmp 0x10989a
movq %r11, %rsi
movq $-0x1, %rdi
cvtsi2sd %rdi, %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %r10, %xmm0
movsd 0x12fe02(%rip), %xmm1   # 0x2396b8
mulsd %xmm0, %xmm1
ucomisd %xmm2, %xmm1
movq $-0x1, %rdi
cmovaq %rdi, %r13
movq %r13, 0x8(%rsp)
leaq 0x1(%rsi), %r12
leaq -0x1(%rdx), %r8
movq $-0x1, %rcx
movq $-0x1, %r14
cmpq %r8, %r12
jge 0x1099a8
movq %r15, (%rsp)
movq %r9, %r8
movl $0x2, %r13d
subq %rdx, %r13
movq %r12, %rbp
movq (%rax,%rbp,8), %r15
cmpq -0x8(%rax,%rbp,8), %r15
jl 0x10992e
cmpq 0x8(%rax,%rbp,8), %r15
setge %bl
cmpq %r14, %r15
setg %r11b
movq %rbp, %r9
testb %r11b, %bl
jne 0x109928
movq %rcx, %r9
movq %r14, %r15
movq %r9, %rcx
movq %r15, %r14
leaq 0x1(,%rbp), %r9
addq %r13, %r9
incq %rbp
cmpq $0x1, %r9
jne 0x109900
cmpq $-0x1, %r14
je 0x10999a
cmpq %rsi, %rcx
movq %r8, %r9
movq (%rsp), %r15
jle 0x1099a8
cmpq %rcx, %r12
jge 0x10996c
movq (%rax,%r12,8), %r8
cmpq %r10, %r8
cmovlq %r8, %r10
incq %r12
cmpq %r12, %rcx
jne 0x109959
xorps %xmm2, %xmm2
cvtsi2sd %r14, %xmm2
movsd 0x127c4c(%rip), %xmm3   # 0x2315c8
mulsd %xmm0, %xmm3
ucomisd %xmm2, %xmm3
jbe 0x109ae9
movq $-0x1, %rcx
movq $-0x1, %r14
jmp 0x1099a8
movq $-0x1, %r14
movq %r8, %r9
movq (%rsp), %r15
xorps %xmm2, %xmm2
cvtsi2sd %r14, %xmm2
ucomisd %xmm2, %xmm1
cmovaq %rdi, %rcx
movq %rdi, (%r9)
movq 0x18(%rsp), %r14
movq %rdi, (%r14)
testq %r15, %r15
je 0x1099e7
movq (%r15), %r13
cmpq %rdx, %r13
jge 0x1099e7
xorps %xmm1, %xmm1
cvtsi2sdq (%rax,%r13,8), %xmm1
mulsd 0x127be7(%rip), %xmm0   # 0x2315c8
ucomisd %xmm1, %xmm0
jb 0x1099ee
movq $-0x1, %r13
leaq 0x18bd63(%rip), %rax    # 0x295758
cmpl $0x0, 0x130(%rax)
je 0x109a62
movq 0x70(%rsp), %r10
movslq 0xd4(%rax), %rbp
movslq 0xd0(%rax), %rdi
testq %rcx, %rcx
movq 0x8(%rsp), %rdx
cmovgq %rsi, %rdx
movq %rsi, %r8
cmovgq %rcx, %r8
testq %r10, %r10
jle 0x109a9b
movq %rdi, (%rsp)
movq %r9, %r12
movq 0x10(%rsp), %rax
movl 0x14(%rax), %r11d
andq $0x7fffffff, %r11       # imm = 0x7FFFFFFF
je 0x109a67
movq 0x20(%rax), %rdi
xorl %eax, %eax
xorl %r15d, %r15d
movl (%rdi,%r15,8), %ebx
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
addq %rbx, %rax
incq %r15
cmpq %r15, %r11
jne 0x109a4b
jmp 0x109a69
movq %rsi, (%r14)
jmp 0x109ab4
xorl %eax, %eax
cmpq %r10, %rax
jb 0x109a94
xorl %edx, %edx
divq %r10
leaq 0x24(%rsp), %r15
movl $0xffffffff, (%r15)     # imm = 0xFFFFFFFF
movl %eax, %edi
movq 0x8(%rsp), %rdx
movq %r15, %r8
callq 0x11eaa6
movslq %eax, %r8
movslq (%r15), %rdx
movq %r12, %r9
movq (%rsp), %rdi
cmpl $-0x1, %ebp
je 0x109aa8
movq %rbp, (%r9)
movq %rdi, (%r14)
jmp 0x109ab4
cmpq $-0x1, %rdx
je 0x109ac3
movq %rdx, (%r9)
movq %r8, (%r14)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorps %xmm0, %xmm0
cvtsi2sd %edi, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r8, %xmm1
movsd 0x127a96(%rip), %xmm2   # 0x231570
mulsd %xmm1, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x109b27
movq %r8, (%r9)
jmp 0x109aa3
xorps %xmm3, %xmm3
cvtsi2sd %r10, %xmm3
mulsd 0x127a9f(%rip), %xmm2   # 0x231598
ucomisd %xmm2, %xmm3
ja 0x10998a
leaq (%rsi,%rsi,2), %r8
cmpq %r8, %rcx
jle 0x1099a8
jmp 0x10998a
movq $-0x1, %r13
movq %rbx, %r9
movq %r8, %r15
jmp 0x1098a1
cmpq $-0x1, %r13
je 0x109b75
xorps %xmm2, %xmm2
cvtsi2sd %r13, %xmm2
movsd 0x127a73(%rip), %xmm3   # 0x2315b0
mulsd %xmm2, %xmm3
ucomisd %xmm3, %xmm1
mulsd 0x127af3(%rip), %xmm2   # 0x231640
jb 0x109b5d
ucomisd %xmm1, %xmm2
jb 0x109b5d
movq %r8, (%r9)
jmp 0x109ab4
addsd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jb 0x109b75
addsd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
jae 0x109aa3
movq 0x68(%rsp), %rax
movq 0x60(%rsp), %rcx
movq %rdi, (%rcx)
movq %r8, (%rax)
jmp 0x109ab4