// File: /workspace/github_cpp_makefile_star2_O3/robertomaldonado[P]HypercubeTopologyRouting/links.cpp
// Function: main
int main(int argc, char * argv[]){
    //Check arguments for right input
    if ( !isArgCountCorrect ( argc ) ) return 1;
    total_nodes = std::stoi(argv[1]);
    if ( !isPowerOfTwo(total_nodes) ) return 1;
    string routing_model = argv[2];
    if ( !isValidOption(routing_model) ) return 1;
    bits_for_node = log2(total_nodes);

    //Create a vector to hold a binary representation
    map<int, vector<int> > nodes_map;
    create_map( nodes_map );
    printf("%s", map_to_bin_str( nodes_map, total_nodes).c_str() );

    //TO-DO: Get source and destination from the console*/
    int source = 1, destination = 30, path = 10;

    if( routing_model == "dim" ){

        // int len = dim_order_routing(source, destination, &path );
        printf("Dimensional order routing\n");
        while(1){
            printf("input src dst : ");
            cin >> source; cin >> destination; 

            int bits_to_change =  source^destination;

            vector<bool> vector_src = int_to_bin_vector( bits_for_node, source);
            vector<bool> xor_guide = int_to_bin_vector( bits_for_node, bits_to_change);
            vector<int> dim_ord_route;
            int current;
            dim_ord_route.push_back( source );

            for(int i = 0 ; i < xor_guide.size() ; i++){
                if(xor_guide[i]) {
                    vector_src[i] = !vector_src[i];
                    current = bin_vector_to_int( bits_for_node, vector_src);
                    dim_ord_route.push_back( current );
                }
            }
            printf("path from %d to %d: ", source, destination);
            print_single_route(bits_for_node, dim_ord_route);
        
            if( (source > (total_nodes - 1)) ||  (destination > (total_nodes - 1)) ){
                printf( "dim_order_routing: src %d, dst %d, out of bound 0..%d",
                source, destination, total_nodes);
                return 1;
            }
        }

    }else if(routing_model == "all"){

        // int allpath[MAX_PATH][MAXZ_PATH_LEN];
        // int allpath_routing(source, destination, allpath);
        printf("All shortest path routing\n");

        while(1){
            printf("input src dst : ");
            cin >> source; cin >> destination;  

            //XOR to get a get a guide on which bits need to be changed
            int bits_to_change =  source^destination;
            //Convert source and guide to vector of bits
            vector<bool> vector_src = int_to_bin_vector( bits_for_node, source);
            vector<bool> vector_dst = int_to_bin_vector( bits_for_node, destination);
            vector<bool> xor_guide = int_to_bin_vector( bits_for_node, bits_to_change);
            vector<int> all_ord_route;
            //The structure of neighbors is hold in a map.
            //To store here the path for each route found.
            map<int, vector<int> > paths_map;

            int current;
            //The source is the first node
            all_ord_route.push_back( source );
            //For each  bit changed on on the guide, flip the bit
            recursive_flip(vector_src, vector_dst, xor_guide);

            paths_map[ 0 ] = all_ord_route;
            paths_map[ 1 ] = all_ord_route;

            map<int, vector<int> >::iterator it = paths_map.begin();
            int counter = 0;
            for (int i = 0; i < xor_guide.size(); i++ )
                if( xor_guide[i] )
                    counter++;

            printf("%d shortest paths from %d to %d: \n", factorial(counter), source, destination);
            print_multiple_routes(paths_map);

            if( (source > (total_nodes - 1)) ||  (destination > (total_nodes - 1)) ){
                printf( "dim_order_routing: src %d, dst %d, out of bound 0..%d",
                source, destination, total_nodes);
                return 1;
            }
        }
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1f8, %rsp            # imm = 0x1F8
movq %rsi, %rbx
callq 0x42d0
movl $0x1, %r14d
testl %eax, %eax
je 0x2cf6
movq 0x8(%rbx), %rsi
leaq -0x1f8(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x20c0
movq -0x1f8(%rbp), %r15
callq 0x2040
movq %rax, %r14
movl (%rax), %r13d
movl $0x0, (%rax)
leaq -0xc0(%rbp), %r12
movq %r15, %rdi
movq %r12, %rsi
movl $0xa, %edx
callq 0x21f0
cmpq %r15, (%r12)
je 0x2d0b
movslq %eax, %rcx
cmpq %rax, %rcx
jne 0x2d17
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x2d17
testl %ecx, %ecx
jne 0x25e2
movl %r13d, (%r14)
movl %eax, 0x5ba0(%rip)      # 0x8188
leaq -0x1e8(%rbp), %rcx
movq -0x10(%rcx), %rdi
cmpq %rcx, %rdi
je 0x2603
callq 0x2180
movl 0x5b85(%rip), %eax      # 0x8188
movl %eax, %edi
callq 0x432b
testl %eax, %eax
movl $0x1, %r14d
je 0x2cf6
movq 0x10(%rbx), %rsi
leaq -0x1c8(%rbp), %rdi
leaq -0x1f8(%rbp), %rdx
callq 0x20c0
leaq -0x208(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x1c8(%rbp), %rsi
movq -0x1c0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x218(%rbp), %rdi
callq 0x3be6
leaq -0x218(%rbp), %rdi
callq 0x43b8
movl %eax, %ebx
movq -0x218(%rbp), %rdi
cmpq %r14, %rdi
je 0x2676
callq 0x2180
testl %ebx, %ebx
je 0x2a69
cvtsi2sdl 0x5b02(%rip), %xmm0 # 0x8188
callq 0x2290
cvttsd2si %xmm0, %eax
movl %eax, 0x5af7(%rip)      # 0x818c
leaq -0x1f0(%rbp), %rax
movl $0x0, (%rax)
xorl %ecx, %ecx
movq %rcx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rcx, 0x20(%rax)
leaq -0x1f8(%rbp), %rdi
callq 0x2f97
movl 0x5ac2(%rip), %edx      # 0x8188
leaq -0xc0(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x4438
leaq -0xb0(%rbp), %rbx
movq -0x10(%rbx), %rsi
leaq 0x2935(%rip), %rdi      # 0x5020
xorl %eax, %eax
callq 0x2050
movq -0x10(%rbx), %rdi
cmpq %rbx, %rdi
je 0x2700
callq 0x2180
movl $0x1, -0x2c(%rbp)
movl $0x1e, -0x30(%rbp)
leaq 0x290e(%rip), %rsi      # 0x5023
leaq -0x1c8(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x2a74
leaq 0x2953(%rip), %rsi      # 0x5083
leaq -0x1c8(%rbp), %rdi
callq 0x2090
movl $0x0, -0x34(%rbp)
testl %eax, %eax
jne 0x2cd1
leaq 0x29dd(%rip), %rdi      # 0x512f
callq 0x2230
xorl %r15d, %r15d
movq 0x587f(%rip), %r13      # 0x7fe0
leaq -0xc0(%rbp), %r14
movl $0x0, -0x34(%rbp)
leaq 0x28b1(%rip), %rdi      # 0x5027
xorl %eax, %eax
callq 0x2050
movq %r13, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x2100
movq %r13, %rdi
leaq -0x30(%rbp), %rsi
callq 0x2100
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ebx
xorl %edx, %ebx
movl 0x59e9(%rip), %esi      # 0x818c
leaq -0x60(%rbp), %rdi
callq 0x4926
movl 0x59da(%rip), %esi      # 0x818c
movl -0x30(%rbp), %edx
leaq -0x90(%rbp), %rdi
callq 0x4926
movl 0x59c5(%rip), %esi      # 0x818c
leaq -0x1a8(%rbp), %rdi
movl %ebx, %edx
callq 0x4926
xorpd %xmm0, %xmm0
movapd %xmm0, -0x180(%rbp)
movq %r15, -0x170(%rbp)
movl $0x0, -0xb8(%rbp)
movq %r15, -0xb0(%rbp)
leaq -0xb8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq %rax, -0xa0(%rbp)
movq %r15, -0x98(%rbp)
leaq -0x180(%rbp), %rdi
xorl %esi, %esi
leaq -0x2c(%rbp), %rdx
callq 0x3cb4
leaq -0x138(%rbp), %rbx
movq %rbx, %rdi
leaq -0x60(%rbp), %rsi
callq 0x3838
leaq -0xe8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x3838
leaq -0x110(%rbp), %r12
movq %r12, %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x3838
movq %rbx, %rdi
leaq -0xe8(%rbp), %rsi
movq %r12, %rdx
callq 0x3272
movq -0x110(%rbp), %rdi
testq %rdi, %rdi
je 0x28a9
callq 0x2180
movq %r15, -0x110(%rbp)
movl %r15d, -0x108(%rbp)
movq %r15, -0x100(%rbp)
movl %r15d, -0xf8(%rbp)
movq %r15, -0xf0(%rbp)
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x28dd
callq 0x2180
movq %r15, -0xe8(%rbp)
movl %r15d, -0xe0(%rbp)
movq %r15, -0xd8(%rbp)
movl %r15d, -0xd0(%rbp)
movq %r15, -0xc8(%rbp)
movq -0x138(%rbp), %rdi
testq %rdi, %rdi
je 0x2911
callq 0x2180
movq %r15, -0x138(%rbp)
movl %r15d, -0x130(%rbp)
movq %r15, -0x128(%rbp)
movl %r15d, -0x120(%rbp)
movq %r15, -0x118(%rbp)
movl $0x0, -0x38(%rbp)
movq %r14, %rdi
leaq -0x38(%rbp), %rsi
callq 0x38d6
movq %rax, %rdi
leaq -0x180(%rbp), %rsi
callq 0x393e
movl $0x1, -0x38(%rbp)
movq %r14, %rdi
leaq -0x38(%rbp), %rsi
callq 0x38d6
movq %rax, %rdi
leaq -0x180(%rbp), %rsi
callq 0x393e
movq -0x1a8(%rbp), %rcx
movq -0x198(%rbp), %rdx
movl -0x190(%rbp), %eax
subq %rcx, %rdx
shlq $0x3, %rdx
movl $0x1, %esi
addq %rax, %rdx
je 0x29ae
xorl %edi, %edi
xorl %eax, %eax
movl %edi, %r8d
shrl $0x6, %r8d
movq (%rcx,%r8,8), %r8
btq %rdi, %r8
adcl $0x0, %eax
incq %rdi
cmpq %rdi, %rdx
ja 0x297e
testl %eax, %eax
je 0x29ae
movl $0x1, %esi
imull %eax, %esi
leal -0x1(%rax), %ecx
cmpl $0x1, %eax
movl %ecx, %eax
ja 0x29a1
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ecx
leaq 0x26cc(%rip), %rdi      # 0x5087
xorl %eax, %eax
callq 0x2050
movq %r14, %rdi
callq 0x37bc
movl -0x2c(%rbp), %esi
movl 0x57b5(%rip), %ecx      # 0x8188
cmpl %ecx, %esi
setl %al
movl -0x30(%rbp), %edx
cmpl %ecx, %edx
setl %bl
andb %al, %bl
jne 0x29f9
leaq 0x2662(%rip), %rdi      # 0x504d
xorl %eax, %eax
callq 0x2050
movl $0x1, -0x34(%rbp)
movq %r14, %rdi
callq 0x3b5a
movq -0x180(%rbp), %rdi
testq %rdi, %rdi
je 0x2a12
callq 0x2180
movq -0x1a8(%rbp), %rdi
testq %rdi, %rdi
je 0x2a23
callq 0x2180
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2a3f
callq 0x2180
movq $0x0, -0x90(%rbp)
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2a5c
callq 0x2180
movq %r15, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movq %r15, -0x50(%rbp)
testb %bl, %bl
jne 0x276f
jmp 0x2cd1
movl $0x1, %r14d
jmp 0x2ce1
leaq 0x26ce(%rip), %rdi      # 0x5149
callq 0x2230
xorl %r13d, %r13d
movq 0x5556(%rip), %r15      # 0x7fe0
leaq -0xc0(%rbp), %r14
leaq -0x160(%rbp), %rbx
movl $0x0, -0x34(%rbp)
leaq 0x2581(%rip), %rdi      # 0x5027
xorl %eax, %eax
callq 0x2050
movq %r15, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x2100
movq %r15, %rdi
leaq -0x30(%rbp), %rsi
callq 0x2100
movl -0x2c(%rbp), %r15d
movl -0x30(%rbp), %r12d
movl 0x56b9(%rip), %esi      # 0x818c
movq %r14, %rdi
movl %r15d, %edx
callq 0x4926
xorl %r15d, %r12d
movl 0x56a5(%rip), %esi      # 0x818c
leaq -0x60(%rbp), %rdi
movl %r12d, %edx
callq 0x4926
xorpd %xmm0, %xmm0
movapd %xmm0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
leaq -0x2c(%rbp), %rdx
callq 0x3cb4
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movl -0x48(%rbp), %edx
subq %rax, %rcx
shlq $0x3, %rcx
addq %rdx, %rcx
je 0x2c25
xorl %r12d, %r12d
movl $0x1, %edx
movl %r12d, %ecx
shlq %cl, %rdx
movl %r12d, %ecx
shrl $0x6, %ecx
movq (%rax,%rcx,8), %rax
btq %r12, %rax
jae 0x2c07
movq -0xc0(%rbp), %rax
movq (%rax,%rcx,8), %rsi
movq %rdx, %rdi
notq %rdi
andq %rsi, %rdi
movq %rsi, %r8
orq %rdx, %r8
testq %rdx, %rsi
cmovneq %rdi, %r8
movq %r8, (%rax,%rcx,8)
movl 0x560a(%rip), %r15d     # 0x818c
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3838
movl %r15d, %edi
movq %rbx, %rsi
callq 0x4898
movl %eax, -0x1a8(%rbp)
movq -0x160(%rbp), %rdi
testq %rdi, %rdi
je 0x2bd2
callq 0x2180
movq %r13, -0x160(%rbp)
movl %r13d, -0x158(%rbp)
movq %r13, -0x150(%rbp)
movl %r13d, -0x148(%rbp)
movq %r13, -0x140(%rbp)
movq -0x88(%rbp), %rsi
cmpq -0x80(%rbp), %rsi
je 0x2bf4
movl -0x1a8(%rbp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, -0x88(%rbp)
jmp 0x2c07
leaq -0x90(%rbp), %rdi
leaq -0x1a8(%rbp), %rdx
callq 0x3cb4
incq %r12
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movl -0x48(%rbp), %edx
subq %rax, %rcx
leaq (%rdx,%rcx,8), %rcx
cmpq %r12, %rcx
ja 0x2b37
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
leaq 0x2406(%rip), %rdi      # 0x5038
xorl %eax, %eax
callq 0x2050
movl 0x554d(%rip), %edi      # 0x818c
leaq -0x90(%rbp), %rsi
callq 0x31cc
movl -0x2c(%rbp), %esi
movl 0x5534(%rip), %ecx      # 0x8188
cmpl %ecx, %esi
setl %al
movl -0x30(%rbp), %edx
cmpl %ecx, %edx
setl %r15b
andb %al, %r15b
jne 0x2c7c
leaq 0x23df(%rip), %rdi      # 0x504d
xorl %eax, %eax
callq 0x2050
movl $0x1, -0x34(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2c8d
callq 0x2180
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2c9b
callq 0x2180
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x2cc1
callq 0x2180
movq $0x0, -0xc0(%rbp)
movl $0x0, -0xb8(%rbp)
testb %r15b, %r15b
movq 0x5315(%rip), %r15      # 0x7fe0
jne 0x2a9f
leaq -0x1f8(%rbp), %rdi
callq 0x3b5a
movl -0x34(%rbp), %r14d
leaq -0x1b8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x2cf6
callq 0x2180
movl %r14d, %eax
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x23d4(%rip), %rdi      # 0x50e6
callq 0x20f0
leaq 0x23c8(%rip), %rdi      # 0x50e6
callq 0x2200
jmp 0x2ecf
jmp 0x2ecf
movq %rax, %rbx
movq -0x218(%rbp), %rdi
cmpq %r14, %rdi
je 0x2f7a
callq 0x2180
jmp 0x2f7a
movq %rax, %rbx
jmp 0x2f7a
jmp 0x2d54
movq %rax, %rbx
jmp 0x2f8f
movq %rax, %rbx
cmpl $0x0, (%r14)
jne 0x2d68
movl %r13d, (%r14)
leaq -0x1e8(%rbp), %rax
jmp 0x2f81
jmp 0x2ecf
movq %rax, %rbx
jmp 0x2ea5
movq %rax, %rbx
jmp 0x2e7d
movq %rax, %rbx
jmp 0x2dfe
movq %rax, %rbx
jmp 0x2dca
movq %rax, %rbx
movq -0x110(%rbp), %rdi
testq %rdi, %rdi
je 0x2dca
callq 0x2180
xorl %eax, %eax
movq %rax, -0x110(%rbp)
movl %eax, -0x108(%rbp)
movq %rax, -0x100(%rbp)
movl %eax, -0xf8(%rbp)
movq %rax, -0xf0(%rbp)
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x2dfe
callq 0x2180
xorl %eax, %eax
movq %rax, -0xe8(%rbp)
movl %eax, -0xe0(%rbp)
movq %rax, -0xd8(%rbp)
movl %eax, -0xd0(%rbp)
movq %rax, -0xc8(%rbp)
movq -0x138(%rbp), %rdi
testq %rdi, %rdi
je 0x2e4f
callq 0x2180
xorl %eax, %eax
movq %rax, -0x138(%rbp)
movl %eax, -0x130(%rbp)
movq %rax, -0x128(%rbp)
movl %eax, -0x120(%rbp)
movq %rax, -0x118(%rbp)
jmp 0x2e4f
jmp 0x2e4c
jmp 0x2ecf
movq %rax, %rbx
jmp 0x2f43
jmp 0x2e4c
jmp 0x2e4c
jmp 0x2ecf
movq %rax, %rbx
leaq -0xc0(%rbp), %rdi
callq 0x3b5a
movq -0x180(%rbp), %rdi
testq %rdi, %rdi
je 0x2e6c
callq 0x2180
movq -0x1a8(%rbp), %rdi
testq %rdi, %rdi
je 0x2e7d
callq 0x2180
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2ea5
callq 0x2180
xorl %eax, %eax
movq %rax, -0x90(%rbp)
movl $0x0, -0x88(%rbp)
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2f6e
callq 0x2180
xorl %eax, %eax
movq %rax, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movq %rax, -0x50(%rbp)
jmp 0x2f6e
jmp 0x2f10
movq %rax, %rbx
jmp 0x2f6e
movq %rax, %rbx
movq -0x160(%rbp), %rdi
testq %rdi, %rdi
je 0x2f13
callq 0x2180
xorl %eax, %eax
movq %rax, -0x160(%rbp)
movl %eax, -0x158(%rbp)
movq %rax, -0x150(%rbp)
movl %eax, -0x148(%rbp)
movq %rax, -0x140(%rbp)
jmp 0x2f13
movq %rax, %rbx
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2f24
callq 0x2180
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2f43
callq 0x2180
xorl %eax, %eax
movq %rax, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movq %rax, -0x50(%rbp)
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x2f6e
callq 0x2180
xorl %eax, %eax
movq %rax, -0xc0(%rbp)
movl $0x0, -0xb8(%rbp)
movq %rax, -0xb0(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x3b5a
leaq -0x1b8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x2f8f
callq 0x2180
movq %rbx, %rdi
callq 0x2280