// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Correct.cpp
// Function: process_boundary(overlap_region_alloc*, All_reads*, Correct_dumy*, Graph*, Graph*, Cigar_record*, long long, Round2_alignment*, window_list_alloc*)
int process_boundary(overlap_region_alloc* overlap_list, All_reads* R_INF, Correct_dumy* dumy, Graph* g, Graph* DAGCon,
Cigar_record* current_cigar, long long uncorrected_window_start, Round2_alignment* second_round, window_list_alloc* win_ciagr_buf)
{
    char* r_string = dumy->corrected_read;
    long long r_total_length = current_cigar->new_read_length;
    long long corrected_window_start, corrected_window_end;
    int extra_begin;
    int extra_end;

    if(dumy->last_boundary_length == 0)
    {
        return 0;
    }

    corrected_window_start = dumy->last_boundary_length - WINDOW_BOUNDARY/2;
    corrected_window_end = dumy->last_boundary_length + WINDOW_BOUNDARY/2 - 1;

    if(corrected_window_start < 0)
    {
        corrected_window_start = 0;
    }

    if (corrected_window_end >= current_cigar->new_read_length)
    {
        corrected_window_end = current_cigar->new_read_length - 1;
    }

    clear_Graph(g);
    clear_Graph(DAGCon);

    long long x_start, x_end;
    long long x_length, x_len, o_len;
    int threshold; 
    long long Window_Len;
    char* x_string = NULL;
    char* y_string = NULL;
    char* backbone = NULL;
    long long backbone_length;
    long long i;
    long long y_start, y_length;
    long long overlapID, windowID;
    long long startNodeID, endNodeID, currentNodeID;
    int end_site;
    unsigned int error;
    int real_y_start;
    long long total_error = 0;

    backbone = r_string + corrected_window_start;
    backbone_length = corrected_window_end - corrected_window_start + 1;
    addUnmatchedSeqToGraph(g, backbone, backbone_length, &startNodeID, &endNodeID);


    long long correct_x_pos_s;
    long long matched_coverage = 0;
    for (i = 0; i < (long long)dumy->length; i++)
    {
        overlapID = dumy->overlapID[i];
        correct_x_pos_s = (overlap_list->list[overlapID].x_pos_s / WINDOW) * WINDOW;
        windowID = (uncorrected_window_start - correct_x_pos_s) / WINDOW;

        ///skip if window is unmatched
        if (overlap_list->list[overlapID].w_list.a[windowID].y_end == -1)
        {
            continue;
        }

        x_start = overlap_list->list[overlapID].w_list.a[windowID].x_start;
        y_start = overlap_list->list[overlapID].w_list.a[windowID].y_start;

        


        /**
         * There are total 3 cases:
         * 1.  this window of x is overlapped fully by y
         *     x: ------|------|---------
         *     y: ------|------|---------
         *     in this case, x_start == uncorrected_window_start, x_length == WINDOW
         * 2.  the suiffx of x's window is overlapped by the prefix of y
         *     x: ------|------|---------
         *               y: |--|-----------  
         *      in this case, x_start > uncorrected_window_start, x_length < WINDOW
         *      this overlap is useless
         * 3.  the prefix of x's window is overlapped by y (see last window)
         *      x: |------|------|-----|---
         *                 y: |--|-----|------  
         *      or
         *          x: |------|------|-----|----
         *        y: --|------|------|-----|--
         *      
         *      in this case, x_start == uncorrected_window_start, x_length < WINDOW
         * 
         *      case 1 and case 3 are useful, while case 2 is useless
         * **/

        ///case 1 and case 3 are useful
        if(x_start == uncorrected_window_start)
        {
            extra_begin = extra_end = 0;
            x_start = corrected_window_start;
            x_end = corrected_window_end;
            x_len = x_end - x_start + 1;
            threshold = x_len * asm_opt.max_ov_diff_ec;
            /****************************may have bugs********************************/
            threshold = Adjust_Threshold(threshold, x_len);
            /****************************may have bugs********************************/
            ///y_start may less than 0
            y_start = y_start - WINDOW_BOUNDARY/2;

            ///in fact, we don't need this line, just worry for bug
            if(y_start < 0)
            {
                continue;
            }

            Window_Len = x_len + (threshold << 1);

            error =(unsigned int)-1;
            if(determine_overlap_region(threshold, y_start, overlap_list->list[overlapID].y_id, Window_Len, Get_READ_LENGTH((*R_INF), overlap_list->list[overlapID].y_id),
            &extra_begin, &extra_end, &y_start, &o_len))
            {
                fill_subregion(dumy->overlap_region, y_start, o_len, overlap_list->list[overlapID].y_pos_strand, 
                R_INF, overlap_list->list[overlapID].y_id, extra_begin, extra_end);

                x_string = r_string + x_start;
                y_string = dumy->overlap_region;

                ///both end site and real_y_start have extra_begin
                ///should be improved, since most of overlaps are exact overlaps
                ///we can do it quickly
                end_site = Reserve_Banded_BPM_PATH(y_string, Window_Len, x_string, x_len, threshold, &error, &real_y_start,
                        &(dumy->path_length), dumy->matrix_bit, dumy->path, -1, -1);
            }

            

            ///try to calculate using higher threshold
            if(error==(unsigned int)-1)
            {
                extra_begin = extra_end = 0;
                x_start = corrected_window_start;
                x_end = corrected_window_end;
                x_len = x_end - x_start + 1;
                threshold = threshold * 2;
                /****************************may have bugs********************************/
                threshold = Adjust_Threshold(threshold, x_len);
                /****************************may have bugs********************************/
                if(x_len >= 300 && threshold < THRESHOLD_MAX_SIZE)
                {
                    threshold = THRESHOLD_MAX_SIZE;
                }
                if(threshold > THRESHOLD_MAX_SIZE)
                {
                    threshold = THRESHOLD_MAX_SIZE;
                }
                Window_Len = x_len + (threshold << 1);
                y_start = overlap_list->list[overlapID].w_list.a[windowID].y_start - WINDOW_BOUNDARY/2;

                ///in fact, we don't need this line, just worry for bug
                if(y_start < 0)
                {
                    continue;
                }

                error =(unsigned int)-1;
                if(determine_overlap_region(threshold, y_start, overlap_list->list[overlapID].y_id, Window_Len, Get_READ_LENGTH((*R_INF), overlap_list->list[overlapID].y_id),
                &extra_begin, &extra_end, &y_start, &o_len))
                {
                    fill_subregion(dumy->overlap_region, y_start, o_len, overlap_list->list[overlapID].y_pos_strand, 
                    R_INF, overlap_list->list[overlapID].y_id, extra_begin, extra_end);

                    x_string = r_string + x_start;
                    y_string = dumy->overlap_region;

                    ///both end site and real_y_start have extra_begin
                    ///should be improved, since most of overlaps are exact overlaps
                    ///we can do it quickly
                    end_site = Reserve_Banded_BPM_PATH(y_string, Window_Len, x_string, x_len, threshold, &error, &real_y_start,
                            &(dumy->path_length), dumy->matrix_bit, dumy->path, -1, -1);
                }
            }

            if (error!=(unsigned int)-1)
            {

                

                total_error = total_error + error;
                matched_coverage++;
                win_ciagr_buf->a[0].x_start = x_start; win_ciagr_buf->a[0].x_end = x_end;
                win_ciagr_buf->c.n = 0;
                generate_cigar(dumy->path, dumy->path_length, &(win_ciagr_buf->a[0]), win_ciagr_buf, &real_y_start, &end_site, &error, x_string, x_len, y_string);  
                ///both end site and real_y_start have extra_begin
                real_y_start -= extra_begin;
                end_site -= extra_begin;

                y_length = end_site - real_y_start + 1;
                y_start = y_start + real_y_start;
                

                x_start = corrected_window_start;
                x_length = corrected_window_end - x_start + 1;

                ///here can be improved, make y_string = dumy->overlap_region + real_y_start + extra_begin
                recover_UC_Read_sub_region(dumy->overlap_region, y_start, y_length, overlap_list->list[overlapID].y_pos_strand, 
                R_INF, overlap_list->list[overlapID].y_id);

                x_string = r_string + x_start;
                y_string = dumy->overlap_region;

                currentNodeID = x_start - corrected_window_start;
                
                addmatchedSeqToGraph(g, currentNodeID, x_string, x_length, y_string, y_length, &(win_ciagr_buf->a[0]), win_ciagr_buf, startNodeID, endNodeID);
            }

        }///case 2 is useless
        else if(x_start != uncorrected_window_start)
        {
            continue;
        }        
    }


    if(matched_coverage >= MIN_COVERAGE_THRESHOLD)
    {
        ///if there are no error, we do not need correction
        if(total_error == 0)
        {
            return 0;
        }
        
        clear_Cigar_record(&(second_round->tmp_cigar));
        clear_Correct_dumy_pure(&(second_round->dumy));

        ///correct bases in [start_base, end_base]
        long long start_base = corrected_window_start + WINDOW_UNCORRECT_SINGLE_SIDE_BOUNDARY;
        long long end_base = corrected_window_end - WINDOW_UNCORRECT_SINGLE_SIDE_BOUNDARY;

        if(end_base > start_base)
        {
            ///note there is an additional "S" node
            ///and start from i-th node, we can correct (i+1)-th base
            /// so the condition when traversing graph is 
            ///(node >= start_base - corrected_window_start && node <= end_base - corrected_window_start)
            get_seq_from_Graph(g, DAGCon, &(second_round->dumy), &(second_round->tmp_cigar), backbone, 
            r_string, r_total_length, corrected_window_start);
            
            /**
            if(verify_cigar_2(backbone, backbone_length, second_round->dumy.corrected_read, 
                second_round->dumy.corrected_read_length, &(second_round->tmp_cigar), -1))
            {
                fprintf(stderr, "hahah\n");
            }
            **/
            
            merge_cigars(dumy, current_cigar, second_round, start_base, end_base,
            corrected_window_start, corrected_window_end);
            


        }
        
    }
    else
    {
        return 0;
    }

    return 1;
    
    
    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %r8, 0xb8(%rsp)
movq 0x10(%rdx), %rax
testq %rax, %rax
je 0x4e370
movq %rcx, %r12
movq %rdi, 0x20(%rsp)
movq %rsi, 0x28(%rsp)
movq (%rdx), %rbx
movl 0x20(%r9), %r13d
leaq 0xba(%rax), %rcx
cmpq $0xbc, %rax
movl $0xbb, %r14d
cmovgeq %rax, %r14
leaq -0xbb(%r14), %r15
leal -0x1(%r13), %ebp
cmpq %r13, %rcx
cmovlq %rcx, %rbp
movq %r12, %rdi
movq %rdx, 0x48(%rsp)
callq 0x4495d
movq 0xb8(%rsp), %rdi
callq 0x4495d
movq %rbx, 0xd0(%rsp)
leaq (%rbx,%r14), %rsi
addq $-0xbb, %rsi
movq %rbp, 0xb0(%rsp)
movq %r15, 0xa0(%rsp)
subq %r15, %rbp
movq %rbp, 0x40(%rsp)
leaq 0x1(%rbp), %r15
leaq 0xf0(%rsp), %rcx
leaq 0xe8(%rsp), %r8
movq %r12, %rdi
movq %rsi, 0x38(%rsp)
movq %r15, %rdx
callq 0x4499c
movq 0x48(%rsp), %r10
cmpq $0x0, 0x30(%r10)
jle 0x4e370
movq %r13, 0xc0(%rsp)
movq %r12, 0x80(%rsp)
movq %r14, 0xc8(%rsp)
cvtsi2sd %r15, %xmm1
movq 0x130(%rsp), %r9
leaq 0x50(%r10), %rax
movq %rax, 0x18(%rsp)
leaq 0x7d70(%r10), %rax
movq %rax, 0x60(%rsp)
leaq 0xff0(%r10), %rax
movq %rax, 0x88(%rsp)
leaq 0xa14(%r10), %rax
movq %rax, 0x58(%rsp)
movq $0x0, 0xa8(%rsp)
movabsq $-0x513cc1e098ead65b, %r14 # imm = 0xAEC33E1F671529A5
movq $0x0, 0x90(%rsp)
xorl %r13d, %r13d
movq 0x28(%rsp), %rsi
movq 0x20(%rsp), %rdi
movq 0x40(%rsp), %r8
movsd %xmm1, 0x68(%rsp)
movq %r15, 0x30(%rsp)
movq 0x28(%r10), %rax
imulq $0xa8, (%rax,%r13,8), %r15
movq (%rdi), %r11
movl 0x4(%r11,%r15), %eax
imulq $0x57619f1, %rax, %rax  # imm = 0x57619F1
shrq $0x23, %rax
imull $0x177, %eax, %eax      # imm = 0x177
movq %r9, %rcx
subq %rax, %rcx
movq %rcx, %rax
imulq %r14
movq %rdx, %rbp
addq %rcx, %rbp
movq %rbp, %rax
shrq $0x3f, %rax
sarq $0x8, %rbp
addq %rax, %rbp
movq 0x58(%r11,%r15), %rax
shlq $0x5, %rbp
cmpl $-0x1, 0xc(%rax,%rbp)
je 0x4e27e
addq %rbp, %rax
movslq (%rax), %rcx
cmpq %r9, %rcx
jne 0x4e27e
leaq 0x247949(%rip), %rcx    # 0x295758
movsd 0xc0(%rcx), %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
testl %ecx, %ecx
movl %ecx, %ebx
movl $0x1, %edx
cmovel %edx, %ebx
cmpq $0x3, %r8
movslq 0x8(%rax), %rax
cmovll %ecx, %ebx
cmpq $0xbb, %rax
jl 0x4e27e
leaq -0xbb(%rax), %r14
leal (%rbx,%rbx), %edx
movl $0xffffffff, 0x8(%rsp)  # imm = 0xFFFFFFFF
movl 0x10(%r11,%r15), %r9d
movq 0x18(%rsi), %rcx
movq (%rcx,%r9,8), %r12
cmpq %r14, %r12
jle 0x4dfc8
movslq %edx, %rcx
movl %edx, 0xc(%rsp)
movq 0x30(%rsp), %rdx
movq %r9, 0x70(%rsp)
movq %r8, %r9
movq %rsi, %r8
leaq (%rdx,%rcx), %rsi
movl 0xc(%rsp), %edx
subq %rax, %rcx
leaq (%rcx,%r12), %rax
addq $0xda, %rax
movq %rsi, %rcx
cmpq %rsi, %rax
movq %r8, %rsi
movq %r9, %r8
movq 0x70(%rsp), %r9
jl 0x4dfc8
addq %r15, %r11
movslq %ebx, %rax
subq %rax, %r14
subq %r14, %r12
movq %rcx, 0x50(%rsp)
cmpq %rcx, %r12
cmovgeq %rcx, %r12
movl %ecx, %eax
subl %r12d, %eax
movl %eax, 0x7c(%rsp)
movl %r14d, %eax
negl %eax
testq %r14, %r14
movq %rsi, %r8
movl $0x0, %esi
cmovgq %r14, %rsi
sarq $0x3f, %r14
andl %eax, %r14d
subq %r14, %r12
movzbl 0x1c(%r11), %ecx
movslq %r14d, %rdx
movq %rdx, 0xd8(%rsp)
movq 0x18(%rsp), %rax
leaq (%rax,%rdx), %rdi
movq %rdi, 0xe0(%rsp)
movq %rsi, 0x98(%rsp)
movq %r12, %rdx
callq 0x32ef8
movq 0x18(%rsp), %rdi
movl $0x4e, %esi
movq 0xd8(%rsp), %rdx
callq 0x20e0
addq 0xe0(%rsp), %r12
movslq 0x7c(%rsp), %rdx
movq %r12, %rdi
movl $0x4e, %esi
callq 0x20e0
movzwl %bx, %r8d
movq 0x18(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq 0x30(%rsp), %rcx
leaq 0x8(%rsp), %r9
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
pushq %r12
pushq %r12
pushq 0x68(%rsp)
pushq 0xa0(%rsp)
pushq 0x80(%rsp)
leaq 0x38(%rsp), %rax
pushq %rax
callq 0x85726
movl 0x3c(%rsp), %edx
movsd 0x98(%rsp), %xmm1
movq 0x70(%rsp), %r8
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x78(%rsp), %r10
addq $0x30, %rsp
movl %eax, 0x14(%rsp)
movl 0x8(%rsp), %eax
cmpl %r12d, %eax
jne 0x4e158
testl %ebx, %ebx
movl %edx, %eax
movl $0x1, %ecx
cmovel %ecx, %eax
cmpq $0x3, %r8
cmovll %edx, %eax
cmpl $0x20, %eax
movl $0x1f, %ebx
cmovgel %eax, %ebx
cmpq $0x12b, %r8             # imm = 0x12B
cmovll %eax, %ebx
cmpl $0x1f, %ebx
movl $0x1f, %eax
cmovgel %eax, %ebx
movq (%rdi), %rax
movq 0x58(%rax,%r15), %rcx
movslq 0x8(%rcx,%rbp), %r14
cmpq $0xbb, %r14
jl 0x4e26c
addq $-0xbb, %r14
movl $0xffffffff, 0x8(%rsp)  # imm = 0xFFFFFFFF
movl 0x10(%rax,%r15), %r9d
movq 0x18(%rsi), %rcx
movq (%rcx,%r9,8), %r12
cmpq %r14, %r12
jle 0x4e26c
leal (%rbx,%rbx), %ecx
movslq %ecx, %rcx
movq 0x30(%rsp), %rdx
leaq (%rdx,%rcx), %rbp
subq %r14, %rcx
addq %r12, %rcx
addq $0x1f, %rcx
cmpq %rbp, %rcx
jl 0x4e26c
movslq %ebx, %rcx
subq %rcx, %r14
subq %r14, %r12
cmpq %rbp, %r12
cmovgeq %rbp, %r12
movl %ebp, %ecx
subl %r12d, %ecx
movl %ecx, 0xc(%rsp)
movl %r14d, %ecx
negl %ecx
testq %r14, %r14
movq %rsi, %r8
movl $0x0, %esi
cmovgq %r14, %rsi
sarq $0x3f, %r14
andl %ecx, %r14d
subq %r14, %r12
movzbl 0x1c(%rax,%r15), %ecx
movslq %r14d, %rdi
movq %rdi, 0x50(%rsp)
movq 0x18(%rsp), %rax
addq %rax, %rdi
movq %rdi, 0x70(%rsp)
movq %rsi, 0x98(%rsp)
movq %r12, %rdx
callq 0x32ef8
movq 0x18(%rsp), %rdi
movl $0x4e, %esi
movq 0x50(%rsp), %rdx
callq 0x20e0
addq 0x70(%rsp), %r12
movslq 0xc(%rsp), %rdx
movq %r12, %rdi
movl $0x4e, %esi
callq 0x20e0
movzwl %bx, %r8d
movq 0x18(%rsp), %rdi
movl %ebp, %esi
movq 0x38(%rsp), %rdx
movq 0x30(%rsp), %rcx
leaq 0x8(%rsp), %r9
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
pushq %rbx
pushq %rbx
pushq 0x68(%rsp)
pushq 0xa0(%rsp)
pushq 0x80(%rsp)
leaq 0x38(%rsp), %rax
pushq %rax
callq 0x85726
movsd 0x98(%rsp), %xmm1
movq 0x70(%rsp), %r8
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x78(%rsp), %r10
addq $0x30, %rsp
movl %eax, 0x14(%rsp)
movl 0x8(%rsp), %eax
cmpl %ebx, %eax
je 0x4e26c
movl %eax, %eax
addq %rax, 0x90(%rsp)
incq 0xa8(%rsp)
movq 0x140(%rsp), %rcx
movq 0x10(%rcx), %rdx
movq 0xa0(%rsp), %rax
movl %eax, (%rdx)
movq 0xb0(%rsp), %rax
movl %eax, 0x4(%rdx)
movq $0x0, 0x18(%rcx)
movq 0x60(%rsp), %rax
movl (%rax), %esi
movq 0x58(%rsp), %rdi
leaq 0x10(%rsp), %r8
leaq 0x14(%rsp), %r9
movq 0x18(%rsp), %rbp
pushq %rbp
movq 0x38(%rsp), %r12
pushq %r12
movq 0x48(%rsp), %rbx
pushq %rbx
leaq 0x20(%rsp), %rax
pushq %rax
callq 0x85cd2
addq $0x20, %rsp
movslq 0x10(%rsp), %rsi
movslq %r14d, %rax
subq %rax, %rsi
movl %esi, 0x10(%rsp)
movl 0x14(%rsp), %ecx
subl %eax, %ecx
movl %ecx, 0x14(%rsp)
subl %esi, %ecx
incl %ecx
movslq %ecx, %r14
addq 0x98(%rsp), %rsi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movzbl 0x1c(%rax,%r15), %ecx
movl 0x10(%rax,%r15), %r9d
movq %rbp, %rdi
movq %r14, %rdx
movq 0x28(%rsp), %r8
callq 0x32ef8
movq 0x80(%rsp), %rdi
xorl %esi, %esi
movq %rbx, %rdx
movq %r12, %rcx
movq %rbp, %r8
movq %r14, %r9
pushq 0xe8(%rsp)
pushq 0xf8(%rsp)
movq 0x150(%rsp), %rax
pushq %rax
pushq 0x10(%rax)
callq 0x44a77
movsd 0x88(%rsp), %xmm1
movq 0x60(%rsp), %r8
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x68(%rsp), %r10
addq $0x20, %rsp
movq 0x130(%rsp), %r9
movabsq $-0x513cc1e098ead65b, %r14 # imm = 0xAEC33E1F671529A5
incq %r13
cmpq 0x30(%r10), %r13
jl 0x4dda0
xorl %ebp, %ebp
cmpq $0x3, 0xa8(%rsp)
jl 0x4e372
cmpq $0x0, 0x90(%rsp)
je 0x4e372
xorl %eax, %eax
movq 0x138(%rsp), %r13
movl %eax, 0x8de0(%r13)
movq %rax, 0x8dd8(%r13)
movq %rax, 0x8df8(%r13)
movl %eax, 0x8dc4(%r13)
movb $0x7f, 0x8dc0(%r13)
movq %rax, 0x48(%r13)
movq %rax, 0x20(%r13)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x8(%r13)
movapd %xmm0, 0x30(%r13)
movq 0xc8(%rsp), %r14
addq $-0xa2, %r14
movq 0xb0(%rsp), %r12
addq $-0x19, %r12
movl $0x1, %ebp
cmpq %r14, %r12
jle 0x4e372
leaq 0x8dc0(%r13), %rcx
movq 0x80(%rsp), %rdi
movq 0xb8(%rsp), %rsi
movq %r13, %rdx
movq %r10, %rbx
movq 0x38(%rsp), %r8
movq 0xd0(%rsp), %r9
movq 0xa0(%rsp), %r15
pushq %r15
pushq 0xc8(%rsp)
callq 0x4d0e3
movq %rbx, %rdi
movq %r13, %rdx
movq %r14, %rcx
movq %r12, %r8
movq %r15, %r9
callq 0x4d8e6
addq $0x10, %rsp
jmp 0x4e372
xorl %ebp, %ebp
movl %ebp, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq