// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
movq %r8, 0x20(%rsp)
movq %rdx, %rbp
movq %rsi, 0x18(%rsp)
movq 0xa8(%rdi), %rax
movq 0xb0(%rdi), %rdx
cmpq %rdx, %rax
je 0x4d4cc
movq %rcx, %r15
movq %rdi, %rbx
movq 0x80(%rsp), %rcx
decq %rcx
movq %rcx, 0x30(%rsp)
movl $0x1, %r12d
movq %r9, 0x38(%rsp)
movq %r15, 0x8(%rsp)
movq %rbp, 0x10(%rsp)
movq %rdi, (%rsp)
cmpq %rdx, %rax
jg 0x4d32e
cmpq 0xa8(%rbx), %rax
jl 0x4d32e
movq 0x18(%rbx), %r10
movq %rax, %r15
shlq $0x7, %r15
movq 0x10(%r10,%r15), %rcx
movq 0x30(%r10,%r15), %rdx
testq %rdx, %rdx
jle 0x4d1c9
leaq (%r10,%r15), %rsi
movq 0x20(%rsi), %rsi
addq $0x10, %rsi
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movq $-0x1, %r13
xorl %r14d, %r14d
movq $-0x1, %rbx
xorl %edi, %edi
testq %rcx, %rcx
je 0x4d1a6
movq (%rsi), %r8
subq 0x8(%rsi), %r8
jmp 0x4d1a9
movq (%rsi), %r8
addq %r8, %r14
cmpq %rbx, %r8
cmovgq %r8, %rbx
cmovgl %r12d, %ebp
cmovgq %rdi, %r13
incq %rdi
addq $0x38, %rsi
cmpq %rdi, %rdx
jne 0x4d198
jmp 0x4d1df
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movq $-0x1, %rbx
movq $-0x1, %r13
xorl %r14d, %r14d
testq %rcx, %rcx
movq %rax, 0x28(%rsp)
je 0x4d21e
addq %rcx, %r14
movq 0x18(%rsp), %rdi
movq (%rsp), %r12
movq %r12, %rsi
movq %rax, %rdx
leaq 0x40(%rsp), %rcx
callq 0x4ccc0
movq 0x40(%rsp), %rax
cmpq %rbx, %rax
cmovgq %rax, %rbx
movl $0x2, %eax
cmovgl %eax, %ebp
movq 0x18(%r12), %r10
movq 0x50(%r10,%r15), %rcx
testq %rcx, %rcx
jle 0x4d26d
leaq (%r10,%r15), %rdx
addq $0x40, %rdx
movq (%rdx), %rdx
addq $0x10, %rdx
xorl %esi, %esi
movl $0x1, %r12d
movl $0x3, %r8d
movq 0x28(%rsp), %r9
movq (%rdx), %rdi
addq %rdi, %r14
cmpq %rbx, %rdi
cmovgq %rdi, %rbx
cmovgl %r8d, %ebp
cmovgq %rsi, %r13
incq %rsi
addq $0x38, %rdx
cmpq %rsi, %rcx
jne 0x4d24a
jmp 0x4d278
movl $0x1, %r12d
movq 0x28(%rsp), %r9
xorps %xmm0, %xmm0
cvtsi2sd %rbx, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r14, %xmm1
movapd %xmm1, %xmm2
mulsd 0x1e42f4(%rip), %xmm2   # 0x231588
ucomisd %xmm2, %xmm0
jae 0x4d2f2
testq %r9, %r9
movq 0x38(%rsp), %r14
movq (%rsp), %rbx
jle 0x4d420
movq %r10, %r15
movq 0x88(%rsp), %rcx
leaq (%r9,%rcx), %r8
leaq (%r9,%rcx), %rdx
decq %rdx
cmpq $0x4, %rdx
movl $0x3, %edi
cmovgeq %rdx, %rdi
movq %r9, %rax
addq %rcx, %r9
addq $0x2, %r9
cmpq 0x80(%rsp), %r9
cmovgeq 0x30(%rsp), %r9
cmpq %r8, %r9
jge 0x4d2fe
xorl %esi, %esi
xorl %ecx, %ecx
jmp 0x4d341
movslq %ebp, %r8
movq (%rsp), %rbx
jmp 0x4d3f4
incq %r9
xorl %ecx, %ecx
xorl %r10d, %r10d
movb (%r14,%r8), %sil
testb %r10b, %r10b
je 0x4d31c
cmpb %r10b, %sil
jne 0x4d33e
incq %rcx
movl %r10d, %esi
jmp 0x4d324
movl $0x1, %ecx
movl %esi, %r10d
incq %r8
cmpq %r8, %r9
jne 0x4d306
jmp 0x4d341
movq %rax, %r13
callq 0x595c
movq %r13, %rax
jmp 0x4d4bc
movl %r10d, %esi
addq $-0x3, %rdi
cmpq %rdx, %rdi
jge 0x4d37d
xorl %r8d, %r8d
movq %rdx, %r10
xorl %r11d, %r11d
movb -0x1(%r14,%r10), %r9b
testb %r11b, %r11b
je 0x4d36a
cmpb %r11b, %r9b
jne 0x4d385
incq %r8
movl %r11d, %r9d
jmp 0x4d373
movl $0x1, %r8d
movl %r9d, %r11d
decq %r10
cmpq %rdi, %r10
jg 0x4d353
jmp 0x4d388
xorl %r9d, %r9d
xorl %r8d, %r8d
jmp 0x4d388
movl %r11d, %r9d
movb (%r14,%rdx), %dil
xorl %r11d, %r11d
cmpb %dil, %sil
setne %dl
sete %r11b
cmpb %dil, %r9b
sete %r10b
addq %r11, %rcx
xorl %edi, %edi
cmpq $0x2, %rcx
jg 0x4d3d8
andb %dl, %r10b
movzbl %r10b, %r10d
addq %r10, %r8
cmpq $0x2, %r8
movq %r15, %r10
jg 0x4d3db
cmpb %sil, %r9b
setne %sil
orb %sil, %dl
addq %rcx, %r8
cmpq $0x3, %r8
setl %dil
orb %dl, %dil
jmp 0x4d3db
movq %r15, %r10
mulsd 0x1e41ad(%rip), %xmm1   # 0x231590
ucomisd %xmm1, %xmm0
movq %rax, %r9
jb 0x4d420
testb %dil, %dil
jne 0x4d420
movslq %ebp, %r8
movq %rbx, %rdi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r9, %rcx
movq %r13, %r9
pushq 0x20(%rsp)
movq 0x10(%rsp), %r15
pushq %r15
callq 0x86602
addq $0x10, %rsp
jmp 0x4d4bc
incq %r9
movq %r9, %rcx
shlq $0x7, %rcx
movb 0x18(%r10,%rcx), %bl
movq 0x10(%rsp), %rbp
movq (%rbp), %rax
movq 0x8(%rbp), %rcx
leaq 0x2(%rcx), %rdx
movq 0x18(%rbp), %rsi
movq %r9, %r13
cmpq %rsi, %rdx
jle 0x4d463
addq %rsi, %rsi
movq %rsi, 0x18(%rbp)
movq %rax, %rdi
callq 0x2370
movq %rax, (%rbp)
movq 0x8(%rbp), %rcx
movq 0x8(%rsp), %r15
movb %bl, (%rax,%rcx)
movq (%rbp), %rax
movq 0x8(%rbp), %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, 0x8(%rbp)
movb $0x0, 0x1(%rax,%rcx)
cmpb $0x0, (%r15)
je 0x4d497
movq %r15, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x58afb
jmp 0x4d4ad
movq 0x8(%r15), %rax
movq 0x18(%r15), %rcx
movl -0x4(%rax,%rcx,4), %edx
andl $-0x4, %edx
addl $0x4, %edx
movl %edx, -0x4(%rax,%rcx,4)
movq (%rsp), %rbx
movq %r13, %rax
incl 0x20(%r15)
movb $0x0, (%r15)
movq 0xb0(%rbx), %rdx
cmpq %rdx, %rax
jne 0x4d144
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq