// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/Correct.cpp
// Function: get_seq_from_Graph(Graph*, Graph*, Correct_dumy*, Cigar_record*, char*, char*, long long, long long)
void get_seq_from_Graph(Graph* backbone, Graph* DAGCon, Correct_dumy* dumy, Cigar_record* current_cigar, char* self_string,
char* r_string, long long r_string_length, long long r_string_site)
{
    ///debug_whole_graph(backbone);
    long long currentNodeID;
    long long i;
    // There are several cases: 
    // 1. match 2. mismatch (A, C, G, T, N) 3. deletion 4. insertion (A, C, G, T)
    // in fact, 1. the weight of node itself 2. weight of alignToNode 3. weight of insertion node
    long long max_count;
    int max_type;
    long long  max_edge;
    long long total_count;
    long long current_weight;

    long long max_insertion_count;

    currentNodeID = backbone->s_start_nodeID;

    while (currentNodeID != (long long)backbone->s_end_nodeID)
    {
        total_count = 0;
        max_count = -1;
        max_type = -1;
        max_edge = -1;


        ///if it is a backbone node, there are three types od out-edges
        ///1. mismatch_edges 2. insertion_edges 3. deletion_edges
        if (currentNodeID >= (long long)backbone->s_start_nodeID && currentNodeID <= (long long)backbone->s_end_nodeID)
        {
            ///mismatch_edges
            for (i = 0; i < (long long)backbone->g_nodes.list[currentNodeID].mismatch_edges.length; i++)
            {
                if (backbone->g_nodes.list[currentNodeID].num_insertions != 0)
                {
                    current_weight = backbone->g_nodes.list[currentNodeID].mismatch_edges.list[i].weight -
                        backbone->g_nodes.list[currentNodeID].mismatch_edges.list[i].num_insertions;
                }
                else
                {
                    current_weight = backbone->g_nodes.list[currentNodeID].mismatch_edges.list[i].weight;
                }
                
                
                total_count = total_count + current_weight;

                ///for match, it needs to deal with both match and insertion
                ///if there is a insertion, we need to check this node two times
                ///1. num_insertions > 0, 2. num_insertions=0
                if (current_weight > max_count)
                {
                    max_count = current_weight;
                    max_edge = i;
                    max_type = MISMATCH;
                }
            }

            ///insertion_edges
            if (backbone->g_nodes.list[currentNodeID].num_insertions != 0)
            {
                ///this line must be prior than the next line
                ///since build_DAGCon will set backbone->g_nodes.list[currentNodeID].num_insertions to be 0
                total_count = total_count + backbone->g_nodes.list[currentNodeID].num_insertions;
                
                build_DAGCon(DAGCon, backbone, currentNodeID, &max_insertion_count);

                if(max_insertion_count > max_count)
                {
                    max_count = max_insertion_count;
                    max_type = INSERTION;
                }
            }

            ///deletion_edges
            for (i = 0; i < (long long)backbone->g_nodes.list[currentNodeID].deletion_edges.length; i++)
            {
                total_count = total_count + backbone->g_nodes.list[currentNodeID].deletion_edges.list[i].weight;

                if ((long long)backbone->g_nodes.list[currentNodeID].deletion_edges.list[i].weight > max_count)
                {
                    max_count = backbone->g_nodes.list[currentNodeID].deletion_edges.list[i].weight;
                    max_edge = i;
                    max_type = DELETION;
                }
            }

            ///do correction
            if(max_count >= total_count*(CORRECT_THRESHOLD))
            {
                currentNodeID = add_path_to_correct_read_new(backbone, DAGCon, dumy, currentNodeID, max_type, max_edge, current_cigar,
                self_string);
            }
            else  
            {
                 ///NOTE: currentNodeID = 0 is a tmp node without any sense
                 if(currentNodeID > 0 && if_is_homopolymer_strict(r_string_site + currentNodeID - 1, r_string, r_string_length)
                  && max_count >= total_count*CORRECT_THRESHOLD_HOMOPOLYMER)
                {
                    currentNodeID = add_path_to_correct_read_new(backbone, DAGCon, dumy, currentNodeID, max_type, max_edge, current_cigar,
                    self_string);
                }
                else///don't do correction, directly use the base of next backbone node
                {
                    currentNodeID++;
                    add_base_to_correct_read_directly(dumy, backbone->g_nodes.list[currentNodeID].base);

                    add_cigar_record(&(backbone->g_nodes.list[currentNodeID].base), 1, current_cigar, 0);
                }
            }
            
        }
        else  ///if there is a non-backbone node
        {
            fprintf(stderr, "error\n");
        }
        
    }

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, 0x38(%rsp)
movq %r8, 0x28(%rsp)
movq %rcx, 0x10(%rsp)
movq %rdx, 0x8(%rsp)
movq %rsi, 0x18(%rsp)
movq %rdi, %r13
movq 0x98(%rsp), %rcx
movq 0xa8(%rdi), %rax
decq %rcx
movq %rcx, 0x30(%rsp)
movq 0x23368f(%rip), %rbx    # 0x252fe0
leaq 0x1c4015(%rip), %r15    # 0x1e396d
pushq $0x6
popq %r12
pushq $0x1
popq %rbp
pushq $0x1
popq %r14
pushq $0x3
popq %r11
movq %rdi, 0x20(%rsp)
movq %rax, (%rsp)
cmpq 0xb0(%r13), %rax
je 0x1fbe7
jg 0x1f988
cmpq 0xa8(%r13), %rax
jge 0x1f9a3
movq (%rbx), %rcx
movq %r15, %rdi
movq %r12, %rsi
movq %rbp, %rdx
callq 0x2410
movq (%rsp), %rax
pushq $0x3
popq %r11
jmp 0x1f970
movq 0x18(%r13), %rcx
movq %rax, %r13
movq %rcx, %rax
shlq $0x7, %r13
leaq (%rcx,%r13), %rdx
movq 0x10(%rcx,%r13), %rcx
movq 0x30(%rax,%r13), %rsi
testq %rsi, %rsi
movl $0x0, %edi
cmovleq %rdi, %rsi
pushq $0x10
popq %rdi
xorl %r8d, %r8d
pushq $-0x1
popq %r15
movq %r15, %rbp
pushq $-0x1
popq %r12
xorl %ebx, %ebx
cmpq %r8, %rsi
je 0x1fa16
movq 0x20(%rdx), %r10
testq %rcx, %rcx
je 0x1f9f7
movq (%r10,%rdi), %r9
subq 0x8(%r10,%rdi), %r9
jmp 0x1f9fb
movq (%r10,%rdi), %r9
addq %r9, %rbx
cmpq %rbp, %r9
cmovgq %r9, %rbp
cmovgl %r14d, %r12d
cmovgq %r8, %r15
incq %r8
addq $0x38, %rdi
jmp 0x1f9de
testq %rcx, %rcx
je 0x1fa56
addq %rcx, %rbx
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
movq (%rsp), %rdx
leaq 0x50(%rsp), %rcx
callq 0x1f5d8
pushq $0x3
popq %r11
movq 0x50(%rsp), %rax
cmpq %rbp, %rax
cmovgq %rax, %rbp
pushq $0x2
popq %rax
cmovgl %eax, %r12d
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
leaq (%rax,%r13), %rcx
addq $0x40, %rcx
movq 0x10(%rcx), %rdx
testq %rdx, %rdx
movl $0x0, %esi
cmovleq %rsi, %rdx
pushq $0x10
popq %rsi
xorl %edi, %edi
movq 0x20(%rsp), %r13
cmpq %rdi, %rdx
je 0x1fa9f
movq (%rcx), %r8
movq (%r8,%rsi), %r8
addq %r8, %rbx
cmpq %rbp, %r8
cmovgq %r8, %rbp
cmovgl %r11d, %r12d
cmovgq %rdi, %r15
incq %rdi
addq $0x38, %rsi
jmp 0x1fa78
cvtsi2sd %rbp, %xmm1
cvtsi2sd %rbx, %xmm2
movapd %xmm2, %xmm0
mulsd 0x1c3a23(%rip), %xmm0   # 0x1e34d8
ucomisd %xmm0, %xmm1
movslq %r12d, %r12
jae 0x1fb44
movq (%rsp), %rcx
testq %rcx, %rcx
pushq $0x1
popq %rbp
jle 0x1fb92
movq 0x30(%rsp), %rax
leaq (%rax,%rcx), %rdi
movq 0x38(%rsp), %rsi
movq 0x90(%rsp), %rdx
movsd %xmm1, 0x48(%rsp)
movsd %xmm2, 0x40(%rsp)
callq 0x52f6d
movsd 0x40(%rsp), %xmm1
mulsd 0x1c39d9(%rip), %xmm1   # 0x1e34e0
movsd 0x48(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x1fb8a
testl %eax, %eax
je 0x1fb8a
movq %r13, %rdi
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %rdx
movq (%rsp), %rcx
movq %r12, %r8
movq %r15, %r9
pushq 0x28(%rsp)
pushq 0x18(%rsp)
callq 0x52dd1
addq $0x10, %rsp
jmp 0x1fbcc
movq %r13, %rdi
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %rdx
movq (%rsp), %rcx
movq %r12, %r8
movq %r15, %r9
pushq 0x28(%rsp)
pushq 0x18(%rsp)
callq 0x52dd1
addq $0x10, %rsp
movq 0x23346d(%rip), %rbx    # 0x252fe0
leaq 0x1c3df3(%rip), %r15    # 0x1e396d
pushq $0x6
popq %r12
pushq $0x1
popq %rbp
pushq $0x3
popq %r11
jmp 0x1f96c
movq 0x18(%r13), %rax
movq (%rsp), %rcx
incq %rcx
movq %rcx, %rbx
shlq $0x7, %rbx
movsbl 0x18(%rax,%rbx), %esi
movq 0x8(%rsp), %rdi
movq %rcx, %r15
callq 0x5307f
movq 0x18(%r13), %rax
leaq (%rax,%rbx), %rdi
addq $0x18, %rdi
movl %r14d, %esi
movq 0x10(%rsp), %rdx
xorl %ecx, %ecx
callq 0x109b4
movq %r15, %rax
movq 0x23340d(%rip), %rbx    # 0x252fe0
leaq 0x1c3d93(%rip), %r15    # 0x1e396d
pushq $0x6
popq %r12
pushq $0x3
popq %r11
jmp 0x1f96c
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq