// File: adamiaonr[P]rid-analytics/src/rid-analytics.cpp
// Function: RID_Analytics::get_origin_distance(RID_Router*)
int RID_Analytics::get_origin_distance(RID_Router * from_router) {

    // check if we're there yet
    if (from_router->get_id() == this->origin_server->get_id())
        return 0;

    uint8_t bitmask_value = (1 << (std::stoi(this->origin_server->get_id()) % 8));
    uint8_t bitmask_byte = (std::stoi(this->origin_server->get_id()) / 8);

    // std::cout << "RID_Analytics::get_origin_distance() : [INFO] "
    //     << "\n\torigin_server_id = " << this->origin_server->get_id() 
    //     << "\n\tbitmask_value = " << (int) bitmask_value 
    //     << "\n\tbitmask_byte = " << (int) bitmask_byte << std::endl;

    int origin_distance = 0;
    RID_Router * next_router = from_router;
    while (next_router->get_id() != this->origin_server->get_id()) {

        // std::cout << "RID_Analytics::get_origin_distance() : [INFO] "
        //     << "\n\tnext router id = " << next_router->get_id() << std::endl;

        // get next router in path
        uint8_t iface_num = next_router->get_iface_num();
        for (uint8_t k = 0; k < iface_num; k++) {

            std::vector<uint8_t> * tree_bitmask = next_router->get_tree_bitmask(k);
            // std::cout << "RID_Analytics::get_origin_distance() : [INFO] "
            //     << "\n\ttree_bitmask = " << (int) tree_bitmask[bitmask_byte] 
            //     << "\n\tbitmask_value = " << (int) bitmask_value << std::endl;

            if ((bitmask_value & (*tree_bitmask)[bitmask_byte]) == bitmask_value) {

                // save the next router in the path in next_router
                next_router = next_router->get_next_hop(k).router;
                // increment the origin distance
                origin_distance++;
                // jump off the cycle
                k = iface_num;
            }
        }
    }

    return origin_distance;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x128(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x35650
movq -0x128(%rbp), %rax
movq 0x80(%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x35650
jmp 0x4e124
leaq -0x38(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x51e30
movb %al, -0x129(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x52f0
leaq -0x38(%rbp), %rdi
callq 0x52f0
movb -0x129(%rbp), %al
testb $0x1, %al
jne 0x4e155
jmp 0x4e17b
movl $0x0, -0x4(%rbp)
jmp 0x4e423
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x52f0
jmp 0x4e42f
movq -0x128(%rbp), %rax
movq 0x80(%rax), %rsi
leaq -0x88(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x35650
movq -0x138(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x303d0
movl %eax, -0x130(%rbp)
jmp 0x4e1b9
movl -0x130(%rbp), %eax
movl %eax, %edx
addl $0x7, %edx
testl %eax, %eax
movl %eax, %ecx
cmovsl %edx, %ecx
andl $0xf8, %ecx
subl %ecx, %eax
movb %al, %cl
movl $0x1, %eax
shll %cl, %eax
movb %al, -0x149(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x52f0
movb -0x149(%rbp), %cl
movq -0x128(%rbp), %rax
movb %cl, -0x65(%rbp)
movq 0x80(%rax), %rsi
leaq -0xb0(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x35650
movq -0x148(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x303d0
movl %eax, -0x13c(%rbp)
jmp 0x4e235
movl -0x13c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movb %al, -0x14a(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x52f0
movb -0x14a(%rbp), %al
movb %al, -0x89(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x35650
movq -0x128(%rbp), %rax
movq 0x80(%rax), %rsi
leaq -0x100(%rbp), %rdi
callq 0x35650
jmp 0x4e2a5
leaq -0xe0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x51ec0
movb %al, -0x14b(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x52f0
leaq -0xe0(%rbp), %rdi
callq 0x52f0
movb -0x14b(%rbp), %al
testb $0x1, %al
jne 0x4e2e5
jmp 0x4e41a
movq -0xc0(%rbp), %rdi
callq 0x51e10
movb %al, -0x101(%rbp)
movb $0x0, -0x102(%rbp)
movzbl -0x102(%rbp), %eax
movzbl -0x101(%rbp), %ecx
cmpl %ecx, %eax
jge 0x4e415
movq -0xc0(%rbp), %rdi
movzbl -0x102(%rbp), %esi
callq 0x51ef0
movq %rax, -0x110(%rbp)
movzbl -0x65(%rbp), %eax
movl %eax, -0x150(%rbp)
movq -0x110(%rbp), %rdi
movzbl -0x89(%rbp), %eax
movl %eax, %esi
callq 0x34d30
movq %rax, %rcx
movl -0x150(%rbp), %eax
movzbl (%rcx), %ecx
andl %ecx, %eax
movzbl -0x65(%rbp), %ecx
cmpl %ecx, %eax
jne 0x4e400
movq -0xc0(%rbp), %rdi
movzbl -0x102(%rbp), %esi
callq 0x35610
movq %rax, -0x120(%rbp)
movb %dl, -0x118(%rbp)
movq -0x120(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
movb -0x101(%rbp), %al
movb %al, -0x102(%rbp)
jmp 0x4e400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x52f0
jmp 0x4e42f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x52f0
jmp 0x4e42f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x52f0
jmp 0x4e42f
jmp 0x4e402
movb -0x102(%rbp), %al
addb $0x1, %al
movb %al, -0x102(%rbp)
jmp 0x4e2fe
jmp 0x4e276
movl -0xb4(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x5920
nopl (%rax,%rax)