// File: ynilu[P]elastic/simulator.cpp
// Function: get_best_OFDM_light_path(int, int, Event&, Phy_graph&)
LightPath* get_best_OFDM_light_path(int source, int destination, Event& event, Phy_graph& p_graph)
{
    Phy_node& src_node = p_graph.get_node(source);
    Phy_node& dst_node = p_graph.get_node(destination);


    if(src_node.num_available_OFDM_transmitter < 1)
    {
        return NULL;
    }

    if(dst_node.num_available_OFDM_receiver < 1)
    {
        return NULL;
    }

    int modulation_level = 0;
    int available_bitrate = 0;
    list<CandidatePath>& c_path_list = p_graph.get_path_list(source, destination);
    Spectrum path_spectrum, best_path_spectrum;
    Path best_p_path;

    best_path_spectrum.slot_st = -1;
    best_path_spectrum.slot_ed = -1;
    best_path_spectrum.weight = DBL_MAX;

    for(auto &c_path : c_path_list)
    {
        int require_slots = num_guardband_slot * 2 + ceil(1.0 * event.bandwidth / c_path.modulation_level / slot_capacity);
        path_spectrum = find_best_spectrum(c_path.path, require_slots, p_graph);
        if(best_path_spectrum.weight > path_spectrum.weight){
            best_p_path = c_path.path;
            best_path_spectrum = path_spectrum;
            modulation_level = c_path.modulation_level;
            available_bitrate = (require_slots - num_guardband_slot * 2) * c_path.modulation_level * slot_capacity - event.bandwidth;
        }
    }
    if(best_path_spectrum.slot_st < 0){
        return NULL;
    }
    LightPath* path = new LightPath();
    path->type = LightPath::OFDM;
    path->p_path = best_p_path;
    path->modulation_level = modulation_level;
    path->available_bitrate = available_bitrate;
    path->weight = best_path_spectrum.weight;
    path->spectrum = best_path_spectrum;
    return path;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movl %edi, -0xc(%rbp)
movl %esi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x1b450
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0x1b450
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x1, 0x2c(%rax)
jge 0x7a60
movq $0x0, -0x8(%rbp)
jmp 0x7d97
movq -0x30(%rbp), %rax
cmpl $0x1, 0x34(%rax)
jge 0x7a77
movq $0x0, -0x8(%rbp)
jmp 0x7d97
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x1b670
movq %rax, -0x40(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x2c120
leaq -0x70(%rbp), %rdi
callq 0x2c120
jmp 0x7aac
leaq -0x98(%rbp), %rdi
callq 0xaed0
movl $0xffffffff, -0x68(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
movsd 0x25562(%rip), %xmm0    # 0x2d030
movsd %xmm0, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
callq 0xc050
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rdi
callq 0xc080
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xc0b0
testb $0x1, %al
jne 0x7b20
jmp 0x7c6f
leaq -0xa8(%rbp), %rdi
callq 0xc0e0
movq %rax, -0xb8(%rbp)
movl 0x3b6cb(%rip), %eax     # 0x43204
addl %eax, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0xf0(%rbp)
movq -0x18(%rbp), %rax
cvtsi2sdl 0x4c(%rax), %xmm0
movq -0xb8(%rbp), %rax
cvtsi2sdl 0x20(%rax), %xmm1
divsd %xmm1, %xmm0
cvtsi2sdl 0x3b690(%rip), %xmm1 # 0x431f8
divsd %xmm1, %xmm0
callq 0x3060
movaps %xmm0, %xmm1
movsd -0xf0(%rbp), %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0xbc(%rbp)
movq -0xb8(%rbp), %rsi
addq $0x8, %rsi
movl -0xbc(%rbp), %edx
movq -0x20(%rbp), %rcx
leaq -0xd8(%rbp), %rdi
callq 0xabd0
jmp 0x7bad
leaq -0x58(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xbc50
leaq -0xd8(%rbp), %rdi
callq 0x2c140
movsd -0x60(%rbp), %xmm0
ucomisd -0x48(%rbp), %xmm0
jbe 0x7c5c
movq -0xb8(%rbp), %rsi
addq $0x8, %rsi
leaq -0x98(%rbp), %rdi
callq 0xbc80
jmp 0x7bf2
leaq -0x70(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0xbc50
movq -0xb8(%rbp), %rax
movl 0x20(%rax), %eax
movl %eax, -0x34(%rbp)
movl -0xbc(%rbp), %eax
movl 0x3b5ec(%rip), %ecx     # 0x43204
shll %ecx
subl %ecx, %eax
movq -0xb8(%rbp), %rcx
imull 0x20(%rcx), %eax
imull 0x3b5ca(%rip), %eax     # 0x431f8
movq -0x18(%rbp), %rcx
subl 0x4c(%rcx), %eax
movl %eax, -0x38(%rbp)
jmp 0x7c5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x7d8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x7d77
jmp 0x7c5e
leaq -0xa8(%rbp), %rdi
callq 0xc110
jmp 0x7b04
cmpl $0x0, -0x68(%rbp)
jge 0x7c8c
movq $0x0, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x7d57
movl $0xf8, %edi
callq 0x3200
movq %rax, -0xf8(%rbp)
jmp 0x7c9f
movq -0xf8(%rbp), %rdi
callq 0x2be50
jmp 0x7cad
movq -0xf8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rax
movl $0x1, 0x8(%rax)
movq -0xe8(%rbp), %rdi
addq $0x68, %rdi
leaq -0x98(%rbp), %rsi
callq 0xbc80
jmp 0x7ce2
movl -0x34(%rbp), %ecx
movq -0xe8(%rbp), %rax
movl %ecx, 0x40(%rax)
movl -0x38(%rbp), %ecx
movq -0xe8(%rbp), %rax
movl %ecx, 0x44(%rax)
movsd -0x60(%rbp), %xmm0
movq -0xe8(%rbp), %rax
movsd %xmm0, 0x48(%rax)
movq -0xe8(%rbp), %rdi
addq $0x50, %rdi
leaq -0x70(%rbp), %rsi
callq 0xbc50
movq -0xe8(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x7d57
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
movl $0xf8, %esi
callq 0x3210
jmp 0x7d77
leaq -0x98(%rbp), %rdi
callq 0xaef0
leaq -0x70(%rbp), %rdi
callq 0x2c140
leaq -0x58(%rbp), %rdi
callq 0x2c140
jmp 0x7d97
leaq -0x98(%rbp), %rdi
callq 0xaef0
leaq -0x70(%rbp), %rdi
callq 0x2c140
leaq -0x58(%rbp), %rdi
callq 0x2c140
jmp 0x7da4
movq -0x8(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x3340
nopl (%rax)