// File: 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
movq %rsp, %rbp
subq $0x80, %rsp
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0xa8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0xb0(%rcx), %rax
je 0x39c5d
movq $0x0, -0x60(%rbp)
movq $-0x1, -0x48(%rbp)
movl $0xffffffff, -0x4c(%rbp) # imm = 0xFFFFFFFF
movq $-0x1, -0x58(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0xa8(%rcx), %rax
jl 0x39c40
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0xb0(%rcx), %rax
jg 0x39c40
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x38(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rcx
cmpq 0x30(%rcx), %rax
jge 0x399ee
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
cmpq $0x0, 0x10(%rax)
je 0x39987
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rax
imulq $0x38, -0x40(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x38(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rcx
movq 0x20(%rcx), %rcx
imulq $0x38, -0x40(%rbp), %rdx
addq %rdx, %rcx
subq 0x18(%rcx), %rax
movq %rax, -0x68(%rbp)
jmp 0x399ae
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rax
imulq $0x38, -0x40(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x399db
movq -0x68(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x1, -0x4c(%rbp)
jmp 0x399dd
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x39900
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
cmpq $0x0, 0x10(%rax)
je 0x39a57
movq -0x60(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x38(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rcx
addq 0x10(%rcx), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x70(%rbp), %rcx
callq 0x39320
movq -0x70(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x39a55
movq -0x70(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x2, -0x4c(%rbp)
jmp 0x39a57
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x38(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rcx
cmpq 0x50(%rcx), %rax
jge 0x39b1d
movq -0x60(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x38(%rbp), %rdx
shlq $0x7, %rdx
addq %rdx, %rcx
movq 0x40(%rcx), %rcx
imulq $0x38, -0x40(%rbp), %rdx
addq %rdx, %rcx
addq 0x10(%rcx), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq 0x40(%rax), %rax
imulq $0x38, -0x40(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
cmpq -0x48(%rbp), %rax
jle 0x39b0a
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq 0x40(%rax), %rax
imulq $0x38, -0x40(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x3, -0x4c(%rbp)
jmp 0x39b0c
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x39a5f
cvtsi2sdq -0x48(%rbp), %xmm0
cvtsi2sdq -0x60(%rbp), %xmm1
movsd 0x3486df(%rip), %xmm2   # 0x382210
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jb 0x39b72
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x38(%rbp), %rcx
movslq -0x4c(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x20(%rbp), %r10
movq -0x28(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xa0360
movq %rax, -0x38(%rbp)
jmp 0x39c3e
cmpq $0x0, -0x38(%rbp)
jle 0x39be9
movq 0x18(%rbp), %rdi
addq -0x38(%rbp), %rdi
subq $0x1, %rdi
movq -0x30(%rbp), %rsi
movq 0x10(%rbp), %rdx
callq 0xa0650
cmpl $0x0, %eax
je 0x39be9
cvtsi2sdq -0x48(%rbp), %xmm0
cvtsi2sdq -0x60(%rbp), %xmm1
movsd 0x34866d(%rip), %xmm2   # 0x382218
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jb 0x39be9
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x38(%rbp), %rcx
movslq -0x4c(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x20(%rbp), %r10
movq -0x28(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xa0360
movq %rax, -0x38(%rbp)
jmp 0x39c3c
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movsbl 0x18(%rax), %esi
callq 0xa0840
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rax
shlq $0x7, %rax
addq %rax, %rdi
addq $0x18, %rdi
movq -0x20(%rbp), %rdx
movl $0x1, %esi
xorl %ecx, %ecx
callq 0x1c6a0
jmp 0x39c3e
jmp 0x39c58
movq 0x38a399(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x348994(%rip), %rsi    # 0x3825e5
movb $0x0, %al
callq 0x22a0
jmp 0x3989a
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)