// File: /workspace/github_cpp_makefile_star2_O2/Luthaf[P]zeopp/cycle.cc
// Function: compute_4cycle(DIJKSTRA_NETWORK*, std::vector<CYCLE, std::allocator<CYCLE>>*, bool, int)
bool compute_4cycle(DIJKSTRA_NETWORK* dnet, vector<CYCLE> *cycles,
                    bool weight_flag, int weight_range)
{
    /* Algorithm (Shortest cycle):
     * 1) For each Dijkstra node, identifiy all the edges from the node.
     * 2) For each edge from the node remove the edge and compute the
     * shortest path between the pair of nodes in the removed edge
     * using the Dijkstra's algorithm.
     */
    // First clear the active flag for each Dijkstra node
    // Set the max_radius of each connection to 1. Used in enabling or
    // disabling a connection without deleting the connection
    // Adds an additional check
    DnIt it = dnet->nodes.begin();
    int count = 0;
    for (; it != dnet->nodes.end(); ++it, ++count) {
        it->active = false;
        CnIt cit = it->connections.begin();
        for (; cit != it->connections.end(); ++cit) cit->max_radius = 1;
    }
    cout << "Length of vornet: " << count << endl;

    it = dnet->nodes.begin();
    for (; it != dnet->nodes.end(); ++it) {
        //cout << "x: " << it->x << " y: " << it->y << " z: " <<  it->z << endl;
        ;
    }
    
    for (int i = 0; i < dnet->nodes.size(); ++i){
        DIJKSTRA_NODE org_node = dnet->nodes.at(i);
        if (i == 0) cout << "org_node: "<< org_node.x << " " << org_node.y << " " << org_node.z << endl;
        CnIt it = org_node.connections.begin();
        int conn_ind = 0;
        for (; it != org_node.connections.end(); ++it, ++conn_ind){
            int path_length = 0;
            int org_node_id = it->from;
            int end_node_id = it->to;
            if (i == 0) cout << "end_node_id: " << end_node_id << endl;
            DIJKSTRA_NODE end_node = dnet->nodes.at(end_node_id);
            
            if (end_node.active) continue;

            CnIt oit = it + 1;       //Check the other connections of begin node
            int oconn_ind=conn_ind + 1;
            for (; oit != org_node.connections.end(); ++oit, ++oconn_ind) {
                int inter_node_id = oit->to;
                if (inter_node_id==org_node_id || inter_node_id==end_node_id) continue;
		if (i==0) cout << "    inter_node_id: " << inter_node_id << endl;
                DIJKSTRA_NODE inter_node = dnet->nodes.at(inter_node_id);
                if (inter_node.active) continue;
                for (CnIt iit = inter_node.connections.begin(); iit != inter_node.connections.end(); ++iit) 
                    if (i==0) cout << "        to: "<< iit->to << endl;
                CnIt eit = end_node.connections.begin();
                int econn_ind=0;
                for (; eit != end_node.connections.end(); ++eit, ++econn_ind) {
                    int final_node_id = eit->to;
                    if (final_node_id==end_node_id || final_node_id==org_node_id) continue;
                    if (i==0) cout << "    final_node_id: " << final_node_id << endl;
                    DIJKSTRA_NODE final_node = dnet->nodes.at(final_node_id);
                    if (final_node.active) continue;

                    CnIt iit = inter_node.connections.begin();
                    for (; iit != inter_node.connections.end(); ++iit) {
                        if (iit->to == final_node_id){  //Cycle found
                            CYCLE new_cycle;
                            new_cycle.length=4;
                            new_cycle.nodes.push_back(org_node);
                            new_cycle.nodes.push_back(end_node);
                            new_cycle.nodes.push_back(inter_node);
                            new_cycle.nodes.push_back(dnet->nodes.at(final_node_id));
                            cycles->push_back(new_cycle);
                        }
                    }
                }
            }
        }
        org_node.active = true;
    }
    cout << "No. of cycles: " << cycles->size() << endl;
    if (!cycles->size()) return false;
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x178, %rsp            # imm = 0x178
movq %rsi, 0x28(%rsp)
movq %rdi, %r15
movq (%rdi), %rax
movq 0x8(%rdi), %rcx
xorl %ebx, %ebx
movabsq $0x3ff0000000000000, %rdx # imm = 0x3FF0000000000000
cmpq %rcx, %rax
je 0xc1b90
movb $0x0, 0x40(%rax)
movq 0x20(%rax), %rsi
movq 0x28(%rax), %rdi
cmpq %rdi, %rsi
je 0xc1b88
movq %rdx, 0x10(%rsi)
addq $0x28, %rsi
jmp 0xc1b79
addq $0x48, %rax
incl %ebx
jmp 0xc1b68
movq 0x8e429(%rip), %r14     # 0x14ffc0
leaq 0x445e1(%rip), %rsi     # 0x10617f
movq %r14, %rdi
callq 0x4480
movq %rax, %rdi
movl %ebx, %esi
callq 0x4760
movq %rax, %rdi
callq 0x4230
leaq 0x118(%rsp), %r12
xorl %r13d, %r13d
movq %r15, 0x18(%rsp)
movq 0x8(%r15), %rax
subq (%r15), %rax
cqto
pushq $0x48
popq %rcx
idivq %rcx
cmpq %r13, %rax
jbe 0xc1f1a
movq %r15, %rdi
movq %r13, %rsi
callq 0xabe2
leaq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0x29ebe
testq %r13, %r13
jne 0xc1c5c
movq %r14, %rdi
leaq 0x4458b(%rip), %rsi     # 0x106192
callq 0x4480
movsd 0x40(%rsp), %xmm0
movq %rax, %rdi
callq 0x46c0
movq %rax, %rdi
leaq 0x428ee(%rip), %rsi     # 0x104512
callq 0x4480
movsd 0x48(%rsp), %xmm0
movq %rax, %rdi
callq 0x46c0
movq %rax, %rdi
leaq 0x428d1(%rip), %rsi     # 0x104512
callq 0x4480
movsd 0x50(%rsp), %xmm0
movq %rax, %rdi
callq 0x46c0
movq %rax, %rdi
callq 0x4230
movq 0x58(%rsp), %rbx
movq %r13, 0x20(%rsp)
cmpq 0x60(%rsp), %rbx
je 0xc1f03
movl (%rbx), %eax
movl %eax, 0xc(%rsp)
movslq 0x4(%rbx), %rax
movq %rax, 0x10(%rsp)
testq %r13, %r13
jne 0xc1ca9
movq %r14, %rdi
leaq 0x4450e(%rip), %rsi     # 0x10619d
callq 0x4480
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x4760
movq %rax, %rdi
callq 0x4230
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0xabe2
leaq 0xc8(%rsp), %rdi
movq %rax, %rsi
callq 0x29ebe
cmpb $0x0, 0x108(%rsp)
movq %rbx, 0x30(%rsp)
movq %rbx, %rax
je 0xc1cf8
leaq 0xe8(%rsp), %rdi
callq 0xaf14
movq 0x30(%rsp), %rbx
addq $0x28, %rbx
movq 0x18(%rsp), %r15
jmp 0xc1c66
leaq 0x28(%rax), %r15
cmpq 0x60(%rsp), %r15
je 0xc1cd8
movl 0x2c(%rax), %ebx
cmpl 0xc(%rsp), %ebx
sete %al
cmpl 0x10(%rsp), %ebx
sete %cl
orb %al, %cl
movq %r15, %rax
jne 0xc1cf8
testq %r13, %r13
jne 0xc1d41
movq %r14, %rdi
leaq 0x44481(%rip), %rsi     # 0x1061ab
callq 0x4480
movq %rax, %rdi
movl %ebx, %esi
callq 0x4760
movq %rax, %rdi
callq 0x4230
movslq %ebx, %rsi
movq 0x18(%rsp), %rdi
callq 0xabe2
leaq 0x80(%rsp), %rdi
movq %rax, %rsi
callq 0x29ebe
cmpb $0x0, 0xc0(%rsp)
je 0xc1d89
leaq 0xa0(%rsp), %rdi
callq 0xaf14
movq %r15, %rax
movq 0x8e241(%rip), %r14     # 0x14ffc0
movq 0x20(%rsp), %r13
jmp 0xc1cf8
movq 0xa0(%rsp), %rbx
movq 0x8e228(%rip), %r14     # 0x14ffc0
movq 0x20(%rsp), %r13
cmpq 0xa8(%rsp), %rbx
je 0xc1dd4
testq %r13, %r13
jne 0xc1dce
movq %r14, %rdi
leaq 0x44409(%rip), %rsi     # 0x1061bf
callq 0x4480
movl 0x4(%rbx), %esi
movq %rax, %rdi
callq 0x4760
movq %rax, %rdi
callq 0x4230
addq $0x28, %rbx
jmp 0xc1d9d
movq 0xe8(%rsp), %r13
cmpq 0xf0(%rsp), %r13
je 0xc1d68
movl 0x4(%r13), %ebp
cmpl 0x10(%rsp), %ebp
je 0xc1e5a
cmpl 0xc(%rsp), %ebp
je 0xc1e5a
cmpq $0x0, 0x20(%rsp)
jne 0xc1e23
movq 0x8e1bb(%rip), %rdi     # 0x14ffc0
leaq 0x443c0(%rip), %rsi     # 0x1061cc
callq 0x4480
movq %rax, %rdi
movl %ebp, %esi
callq 0x4760
movq %rax, %rdi
callq 0x4230
movslq %ebp, %rbx
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0xabe2
leaq 0x130(%rsp), %rdi
movq %rax, %rsi
callq 0x29ebe
cmpb $0x0, 0x170(%rsp)
je 0xc1e63
leaq 0x150(%rsp), %rdi
callq 0xaf14
addq $0x28, %r13
jmp 0xc1ddc
movq 0xa0(%rsp), %r14
cmpq 0xa8(%rsp), %r14
je 0xc1e4d
cmpl %ebp, 0x4(%r14)
jne 0xc1efa
xorps %xmm0, %xmm0
movups %xmm0, (%r12)
andq $0x0, 0x10(%r12)
movabsq $0x4010000000000000, %rax # imm = 0x4010000000000000
movq %rax, 0x110(%rsp)
movq %r12, %rdi
leaq 0x38(%rsp), %rsi
callq 0x3d9ba
movq %r12, %rdi
leaq 0xc8(%rsp), %rsi
callq 0x3d9ba
movq %r12, %rdi
leaq 0x80(%rsp), %rsi
callq 0x3d9ba
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0xabe2
movq %r12, %rdi
movq %rax, %rsi
callq 0x3d9ba
movq 0x28(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0xc2240
movq %r12, %rdi
callq 0xae22
addq $0x28, %r14
jmp 0xc1e6b
movb $0x1, 0x78(%rsp)
leaq 0x58(%rsp), %rdi
callq 0xaf14
incq %r13
jmp 0xc1bc8
movq 0x8e09f(%rip), %rdi     # 0x14ffc0
leaq 0x442b8(%rip), %rsi     # 0x1061e0
callq 0x4480
movq 0x28(%rsp), %rbx
movq 0x8(%rbx), %rsi
subq (%rbx), %rsi
sarq $0x5, %rsi
movq %rax, %rdi
callq 0x42e0
movq %rax, %rdi
callq 0x4230
movq 0x8(%rbx), %rax
cmpq (%rbx), %rax
setne %al
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xc1f6d
jmp 0xc1f6d
movq %rax, %rbx
jmp 0xc1fb4
jmp 0xc1f74
movq %rax, %rbx
jmp 0xc1fa7
jmp 0xc1f7d
jmp 0xc1f7d
movq %rax, %rbx
jmp 0xc1f9a
movq %rax, %rbx
movq %r12, %rdi
callq 0xae22
leaq 0x150(%rsp), %rdi
callq 0xaf14
leaq 0xa0(%rsp), %rdi
callq 0xaf14
leaq 0xe8(%rsp), %rdi
callq 0xaf14
leaq 0x58(%rsp), %rdi
callq 0xaf14
movq %rbx, %rdi
callq 0x4780