// File: /workspace/github_cpp_makefile_star2_O2/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:
movq 0x10(%rdx), %rax
testq %rax, %rax
je 0x208c9
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %r8, %rbx
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, 0x30(%rsp)
movq (%rdx), %rcx
movq %rcx, 0x78(%rsp)
movl 0x20(%r9), %edx
leaq 0xba(%rax), %rcx
cmpq $0xbc, %rax
movl $0xbb, %r12d
cmovgeq %rax, %r12
leaq -0xbb(%r12), %r13
leal -0x1(%rdx), %ebp
movq %rdx, 0xb8(%rsp)
cmpq %rdx, %rcx
cmovlq %rcx, %rbp
movq %rdi, 0x28(%rsp)
movq %r14, %rdi
callq 0x18519
movq %rbx, 0xc0(%rsp)
movq %rbx, %rdi
callq 0x18519
movq %r12, 0xc8(%rsp)
movq 0x78(%rsp), %rax
leaq (%rax,%r12), %rsi
addq $-0xbb, %rsi
movq %rbp, 0x90(%rsp)
movq %r13, 0x80(%rsp)
subq %r13, %rbp
movq %rbp, 0xb0(%rsp)
leaq 0x1(%rbp), %rbx
leaq 0xe0(%rsp), %rcx
leaq 0xd8(%rsp), %r8
movq %r14, 0x88(%rsp)
movq %r14, %rdi
movq %rsi, 0x48(%rsp)
movq %rbx, %rdx
callq 0x18556
movq %rbx, %r9
movq 0x28(%rsp), %rdi
cvtsi2sd %rbx, %xmm1
leaq 0x50(%r15), %rax
movq %rax, 0x60(%rsp)
leaq 0x7d70(%r15), %rax
movq %rax, 0x58(%rsp)
leaq 0xff0(%r15), %rax
movq %rax, 0xa8(%rsp)
leaq 0xa14(%r15), %rax
movq %rax, 0x50(%rsp)
xorl %r12d, %r12d
movl $0x177, %r10d           # imm = 0x177
movl $0x177, %r11d           # imm = 0x177
pushq $0x1
popq %r8
movq $0x0, 0x98(%rsp)
movq $0x0, 0xa0(%rsp)
movq %r15, 0x40(%rsp)
movsd %xmm1, 0x38(%rsp)
movq %rbx, 0x18(%rsp)
cmpq 0x30(%r15), %r12
jge 0x207ea
movq 0x28(%r15), %rax
movq (%rdi), %r13
imulq $0xa8, (%rax,%r12,8), %rbx
movl 0x4(%r13,%rbx), %ecx
movl %ecx, %eax
xorl %edx, %edx
divl %r10d
subl %edx, %ecx
movq 0x120(%rsp), %rsi
movq %rsi, %rax
subq %rcx, %rax
cqto
idivq %r11
movq %rax, %r14
movq 0x58(%r13,%rbx), %rax
shlq $0x5, %r14
cmpl $-0x1, 0xc(%rax,%r14)
je 0x207e2
addq %r14, %rax
movslq (%rax), %rcx
cmpq %rsi, %rcx
jne 0x207e2
movslq 0x8(%rax), %rax
andl $0x0, 0xc(%rsp)
andl $0x0, 0x8(%rsp)
leaq 0x23331f(%rip), %rcx    # 0x253758
movsd 0xc0(%rcx), %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
testl %ecx, %ecx
movl %ecx, %ebp
cmovel %r8d, %ebp
cmpq $0x3, 0xb0(%rsp)
cmovll %ecx, %ebp
leaq -0xbb(%rax), %rsi
movq %rsi, 0x20(%rsp)
cmpq $0xbb, %rax
jl 0x207e2
leal (,%rbp,2), %eax
movl %eax, 0x74(%rsp)
movslq %eax, %r15
orl $-0x1, 0x4(%rsp)
addq %r9, %r15
movl 0x10(%r13,%rbx), %ecx
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0xd0(%rsp)
movq (%rax,%rcx,8), %r8
subq $0x8, %rsp
movl %ebp, %edi
movq %r15, %rcx
leaq 0x10(%rsp), %r9
leaq 0x70(%rsp), %rax
pushq %rax
leaq 0x30(%rsp), %rax
pushq %rax
leaq 0x24(%rsp), %rax
pushq %rax
callq 0x1b53a
addq $0x20, %rsp
testl %eax, %eax
je 0x20560
addq %rbx, %r13
movq 0x20(%rsp), %rsi
movq 0x68(%rsp), %rdx
movzbl 0x1c(%r13), %ecx
movl 0x8(%rsp), %eax
movl 0xc(%rsp), %r10d
movq 0x60(%rsp), %r13
movq %r13, %rdi
movq 0x30(%rsp), %r8
movq 0xd0(%rsp), %r9
pushq %r10
pushq %rax
callq 0x1b475
addq $0x10, %rsp
movzwl %bp, %r8d
movq %r13, %rdi
movl %r15d, %esi
movq 0x48(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0x4(%rsp), %r9
pushq $-0x1
pushq $-0x1
pushq 0x60(%rsp)
pushq 0xc0(%rsp)
pushq 0x78(%rsp)
leaq 0x38(%rsp), %rax
pushq %rax
callq 0x51ff9
addq $0x30, %rsp
movl %eax, 0x14(%rsp)
movl 0x4(%rsp), %eax
pushq $-0x1
popq %rcx
cmpl %ecx, %eax
jne 0x206b1
movq 0x18(%rsp), %r9
andl $0x0, 0xc(%rsp)
andl $0x0, 0x8(%rsp)
testl %ebp, %ebp
movl 0x74(%rsp), %edx
movl %edx, %eax
pushq $0x1
popq %r8
cmovel %r8d, %eax
movq 0xb0(%rsp), %rcx
cmpq $0x3, %rcx
cmovll %edx, %eax
cmpl $0x20, %eax
pushq $0x1f
popq %rdx
movl %edx, %ebp
cmovgel %eax, %ebp
cmpq $0x12b, %rcx            # imm = 0x12B
cmovll %eax, %ebp
cmpl $0x1f, %ebp
cmovgel %edx, %ebp
movq 0x28(%rsp), %rdi
movq (%rdi), %r13
movq 0x58(%r13,%rbx), %rax
movslq 0x8(%rax,%r14), %rax
leaq -0xbb(%rax), %rsi
movq %rsi, 0x20(%rsp)
cmpq $0xbb, %rax
jge 0x205d9
movq 0x40(%rsp), %r15
jmp 0x207d0
leal (,%rbp,2), %eax
movslq %eax, %r14
orl $-0x1, 0x4(%rsp)
addq %r9, %r14
movl 0x10(%r13,%rbx), %r15d
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rax
movq (%rax,%r15,8), %r8
subq $0x8, %rsp
movl %ebp, %edi
movq %r14, %rcx
leaq 0x10(%rsp), %r9
leaq 0x70(%rsp), %rax
pushq %rax
leaq 0x30(%rsp), %rax
pushq %rax
leaq 0x24(%rsp), %rax
pushq %rax
callq 0x1b53a
addq $0x20, %rsp
testl %eax, %eax
je 0x207bd
movq 0x20(%rsp), %rsi
movq 0x68(%rsp), %rdx
movzbl 0x1c(%r13,%rbx), %ecx
movl 0x8(%rsp), %eax
movl 0xc(%rsp), %r10d
movq 0x60(%rsp), %r13
movq %r13, %rdi
movq 0x30(%rsp), %r8
movq %r15, %r9
pushq %r10
pushq %rax
callq 0x1b475
addq $0x10, %rsp
movzwl %bp, %r8d
movq %r13, %rdi
movl %r14d, %esi
movq 0x48(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0x4(%rsp), %r9
pushq $-0x1
pushq $-0x1
pushq 0x60(%rsp)
pushq 0xc0(%rsp)
pushq 0x78(%rsp)
leaq 0x38(%rsp), %rax
pushq %rax
callq 0x51ff9
addq $0x30, %rsp
movl %eax, 0x14(%rsp)
movl 0x4(%rsp), %eax
pushq $-0x1
popq %rcx
cmpl %ecx, %eax
je 0x207bd
movl %eax, %eax
addq %rax, 0x98(%rsp)
incq 0xa0(%rsp)
movq 0x130(%rsp), %rcx
movq 0x10(%rcx), %rdx
movq 0x80(%rsp), %rax
movl %eax, (%rdx)
movq 0x90(%rsp), %rax
movl %eax, 0x4(%rdx)
andq $0x0, 0x18(%rcx)
movq 0x58(%rsp), %rax
movl (%rax), %esi
movq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %r8
leaq 0x14(%rsp), %r9
movq 0x60(%rsp), %rbp
pushq %rbp
pushq 0x20(%rsp)
movq 0x58(%rsp), %r15
pushq %r15
leaq 0x1c(%rsp), %rax
pushq %rax
callq 0x52542
addq $0x20, %rsp
movslq 0x8(%rsp), %rax
movslq 0x10(%rsp), %rsi
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 0x20(%rsp), %rsi
movq %rsi, 0x20(%rsp)
movq 0x28(%rsp), %r13
movq (%r13), %rax
movzbl 0x1c(%rax,%rbx), %ecx
movl 0x10(%rax,%rbx), %r9d
movq %rbp, %rdi
movq %r14, %rdx
movq 0x30(%rsp), %r8
callq 0x6c9e
movq 0x88(%rsp), %rdi
xorl %esi, %esi
movq %r15, %rdx
movq 0x18(%rsp), %rbx
movq %rbx, %rcx
movq %rbp, %r8
movq %r14, %r9
pushq 0xd8(%rsp)
pushq 0xe8(%rsp)
movq 0x140(%rsp), %rax
pushq %rax
pushq 0x10(%rax)
callq 0x18629
movq %r13, %rdi
addq $0x20, %rsp
movq 0x40(%rsp), %r15
pushq $0x1
popq %r8
movq %rbx, %r9
jmp 0x207d0
movq 0x40(%rsp), %r15
movq 0x28(%rsp), %rdi
pushq $0x1
popq %r8
movq 0x18(%rsp), %r9
movsd 0x38(%rsp), %xmm1
movl $0x177, %r10d           # imm = 0x177
movl $0x177, %r11d           # imm = 0x177
incq %r12
jmp 0x203c3
xorl %eax, %eax
cmpq $0x3, 0xa0(%rsp)
jl 0x208cf
cmpq $0x0, 0x98(%rsp)
je 0x208cf
movq 0x128(%rsp), %rbx
andl $0x0, 0x8de0(%rbx)
andq $0x0, 0x8dd8(%rbx)
andq $0x0, 0x8df8(%rbx)
andl $0x0, 0x8dc4(%rbx)
movb $0x7f, 0x8dc0(%rbx)
andq $0x0, 0x48(%rbx)
andq $0x0, 0x20(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rbx)
movaps %xmm0, 0x30(%rbx)
movq 0xc8(%rsp), %r14
addq $-0xa2, %r14
movq 0x90(%rsp), %r13
addq $-0x19, %r13
cmpq %r14, %r13
jle 0x208cc
leaq 0x8dc0(%rbx), %rcx
movq 0x88(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movq %rbx, %rdx
movl %r8d, %ebp
movq 0x48(%rsp), %r8
movq 0x78(%rsp), %r9
movq 0x80(%rsp), %r12
pushq %r12
pushq 0xc0(%rsp)
callq 0x1f909
popq %rax
popq %rcx
subq $0x10, %rsp
movq %r15, %rdi
movq %rbx, %rdx
movq %r14, %rcx
movq %r13, %r8
movq %r12, %r9
callq 0x1feff
popq %rcx
popq %rdx
movl %ebp, %eax
jmp 0x208cf
xorl %eax, %eax
retq
movl %r8d, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq