// File: kiudee[P]VAHD-Projekt/Supervisor.cpp
// Function: Supervisor::Wakeup(NumObj*)
Action Supervisor::Wakeup(NumObj *numo)
{
    if (numo->num > 0) {
        if (numo->num % 8 == 0) {
            printGraph(false);
            printcount++;
        }

        /////////////////////////////////////////////////////
        //////// BEGIN TESTCASE INSERT LEAVE LOOKUP /////////
        //Description: Insert, remove the responsible node, and fire a lookup
        if (false) { //activate testcase
            if (numo->num == 6000) {
                DateObj *dob = new DateObj(89, "me lov subjectz. lolz.");
                Nodes[0]->out->call(Node::Insert, dob);
                //0, 0
            }

            if (numo->num == 2000) {
                //Nodes[54]->out->call(Node::Leave, NONE);
                Nodes[88]->out->call(Node::Leave, NONE);
                //subjects[h(89)]->call(Node::Leave, NONE);
            }

            if (numo->num == 1000) {
                NumObj *numo2 = new NumObj(89);
                Nodes[4]->out->call(Node::LookUp, numo2);
            }
        }

        //////////////////////////////////////////////////
        //////// END TESTCASE INSERT LEAVE LOOKUP ////////
        //////////////////////////////////////////////////


        /////////////////////////////////////////////////////
        //////// BEGIN TESTCASE INSERT JOIN LOOKUP /////////
        //Description: Insert, join a new responsible node, and fire a lookup

        if (true) {
            if (numo->num == 3000) {
                DateObj *dob = new DateObj(666, "some more data.");
                Nodes[4]->out->call(Node::Insert, dob);
                std::shared_ptr<std::ofstream> tmpfile(csvFile);
                InitObj *tempObj = new InitObj(h(666), true, tmpfile);
                new(Node, tempObj);
            }

            if (numo->num == 2000) {

                Nodes[0]->out->call(Node::Join, StartID[total]);
            }

            if (numo->num == 1000) {
                NumObj *numo2 = new NumObj(666);
                Nodes[4]->out->call(Node::LookUp, numo2);
            }
        }


        //////////////////////////////////////////////////
        //////// END TESTCASE INSERT JOIN LOOKUP /////////
        //////////////////////////////////////////////////


        /////////////////////////////////////////////////////
        //////// BEGIN TESTCASE INSERT LOOKUP DELETE /////////
        //Test Insert / Lookup / Delete
        if (false) {
            if (numo->num == 5000) {
                DateObj *dob = new DateObj(14, "me lov subjectz. lolz.");
                Nodes[7]->out->call(Node::Insert, dob);
            }
            if (numo->num == 4000) {
                NumObj *numo2 = new NumObj(14);
                Nodes[5]->out->call(Node::LookUp, numo2);

            }
            if (numo->num == 2000) {
                NumObj *numo3 = new NumObj(14);
                Nodes[0]->out->call(Node::Delete, numo3);
            }
        }

        //////////////////////////////////////////////////
        //////// END TESTCASE INSERT LOOKUP DELETE /////////
        //////////////////////////////////////////////////

        //////////////////////////////////////////////
        /// BEGIN TESTCASE CONTINUOUS LOOKUPS ////////
        // Description: Insert a few data elements and then
        // periodically ask random nodes to Lookup one of
        // these items.
        // Used for csv-file data gathering.
        // Simulationrounds: 15000

        if (false) {
            if (numo->num == 12000) {
                std::uniform_int_distribution<int> distribution(0, total - 1);
                std::mt19937 engine(numo->num);
                auto generator = std::bind(distribution, engine);
                for (int i = 0; i < 10; i++) {
                    DateObj *dob = new DateObj(i, "JustOneTestElement");
                    Nodes[generator()]->out->call(Node::Insert, dob);
                }
            }
            if (numo->num < 12000 && numo->num % 20 == 0) {
                std::uniform_int_distribution<int> nodedist(0, total - 1);
                std::uniform_int_distribution<int> datedist(0, 9);
                std::mt19937 engine(numo->num);
                auto randNode = std::bind(nodedist, engine);
                auto randDate = std::bind(datedist, engine);
                auto numo = new NumObj(randDate());
                Nodes[randNode()]->out->call(Node::LookUp, numo);
            }
        }


        /////////////////////////////////////////////
        /// END TESTCASE CONTINUOUS LOOKUPS  ////////
        ////////////////////////////////////////////


        /////////////////////////////////////////////////////////
        /// BEGIN TESTCASE RETURN SORTED LIST WITH n=100 ////////
        // Description: Routes from left to right. Node 88 is the
        //smallest real node.
        // Simulationrounds: 15000
        if (false) {
            if (numo->num == 1000) {
                NumObj *numo2 = new NumObj(1);
                Nodes[88]->out->call(Node::_DebugRouteFromLeftToRight, numo2);//n=100
                //Nodes[4]->out->call(Node::_DebugRouteFromLeftToRight, numo2);//n=10
            }
        }

        ///////////////////////////////////////////////////////
        /// END TESTCASE RETURN SORTED LIST WITH n=100 ////////
        ///////////////////////////////////////////////////////

        numo->num--;
        call(Supervisor::Wakeup, numo);
    } else {
        delete numo;
        printGraph(true);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jle 0x4434
movq -0x10(%rbp), %rax
movl 0x20(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x3ee4
movq -0xd0(%rbp), %rdi
xorl %esi, %esi
callq 0x4b40
movq -0xd0(%rbp), %rax
movl 0xf8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xf8(%rax)
movq -0x10(%rbp), %rax
cmpl $0xbb8, 0x20(%rax)      # imm = 0xBB8
jne 0x41b9
movl $0x48, %edi
callq 0x31c0
movq %rax, -0xe0(%rbp)
movb $0x1, -0x4d(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x3340
movq -0xd8(%rbp), %rdx
leaq 0x132d2(%rip), %rsi     # 0x171fa
leaq -0x38(%rbp), %rdi
callq 0x5c60
jmp 0x3f33
movq -0xe0(%rbp), %rdi
movl $0x29a, %esi            # imm = 0x29A
leaq -0x38(%rbp), %rdx
callq 0x5dd0
jmp 0x3f4a
movb $0x0, -0x4d(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3100
leaq -0x39(%rbp), %rdi
callq 0x3200
movq -0xe0(%rbp), %rax
movq -0xd0(%rbp), %rdi
movq %rax, -0x18(%rbp)
addq $0x68, %rdi
movl $0x4, %esi
callq 0x5ac0
movq (%rax), %rax
movq 0x28(%rax), %rax
movq %rax, -0xf0(%rbp)
movl $0x38, %edi
callq 0x31c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
leaq 0xd7c4(%rip), %rax      # 0x11770
movq %rax, -0x60(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
leaq -0x18(%rbp), %rcx
callq 0x5ae0
jmp 0x3fcb
movq -0xd0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
movq -0xf0(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
callq *%rax
movq -0xd0(%rbp), %rsi
addq $0x98, %rsi
leaq -0x70(%rbp), %rdi
callq 0x5560
movl $0x40, %edi
callq 0x31c0
movq %rax, -0xf8(%rbp)
jmp 0x4013
movb $0x1, -0x89(%rbp)
movl $0x29a, %edi            # imm = 0x29A
callq 0xdcf0
movsd %xmm0, -0x100(%rbp)
jmp 0x402e
leaq -0x88(%rbp), %rdi
movq %rdi, -0x108(%rbp)
leaq -0x70(%rbp), %rsi
callq 0x5560
movq -0xf8(%rbp), %rdi
movsd -0x100(%rbp), %xmm0
movq -0x108(%rbp), %rdx
movl $0x1, %esi
callq 0x5590
jmp 0x4067
movb $0x0, -0x89(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x5540
movq -0xf8(%rbp), %rax
movq %rax, -0x78(%rbp)
movl $0xe8, %edi
callq 0x31c0
movq %rax, -0x110(%rbp)
jmp 0x4098
movq -0x110(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x5600
jmp 0x40aa
movq -0x110(%rbp), %rdx
movq -0xd0(%rbp), %rsi
movq %rsi, %rdi
callq 0x5720
jmp 0x40c2
leaq -0x70(%rbp), %rdi
callq 0x5540
jmp 0x41b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40f3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3100
leaq -0x39(%rbp), %rdi
callq 0x3200
testb $0x1, -0x4d(%rbp)
jne 0x4104
jmp 0x4115
movq -0xe0(%rbp), %rdi
movl $0x48, %esi
callq 0x31d0
jmp 0x4470
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x38, %esi
callq 0x31d0
jmp 0x4470
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x41ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x4170
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x5540
testb $0x1, -0x89(%rbp)
jne 0x417b
jmp 0x418c
movq -0xf8(%rbp), %rdi
movl $0x40, %esi
callq 0x31d0
jmp 0x41ab
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0xe8, %esi
callq 0x31d0
leaq -0x70(%rbp), %rdi
callq 0x5540
jmp 0x4470
movq -0x10(%rbp), %rax
cmpl $0x7d0, 0x20(%rax)      # imm = 0x7D0
jne 0x4295
movq -0xd0(%rbp), %rdi
addq $0x68, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5ac0
movq (%rax), %rax
movq 0x28(%rax), %rax
movq %rax, -0x128(%rbp)
movl $0x38, %edi
callq 0x31c0
movq %rax, %rcx
movq -0xd0(%rbp), %rax
movq %rcx, -0x118(%rbp)
movq %rcx, -0x120(%rbp)
movq %rax, %rdi
subq $-0x80, %rdi
movslq 0x64(%rax), %rsi
callq 0x5bd0
movq -0x118(%rbp), %rdi
movq %rax, %rcx
leaq 0xf791(%rip), %rax      # 0x139c0
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
callq 0x5ae0
jmp 0x4256
movq -0x120(%rbp), %rdx
movq -0xd0(%rbp), %rsi
movq -0x128(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x4295
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x38, %esi
callq 0x31d0
jmp 0x4470
movq -0x10(%rbp), %rax
cmpl $0x3e8, 0x20(%rax)      # imm = 0x3E8
jne 0x43a7
movl $0x28, %edi
callq 0x31c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x130(%rbp)
movl $0x29a, %esi            # imm = 0x29A
callq 0x5a90
jmp 0x42c9
movq -0xd0(%rbp), %rdi
movq -0x130(%rbp), %rax
movq %rax, -0xa8(%rbp)
addq $0x68, %rdi
movl $0x4, %esi
callq 0x5ac0
movq (%rax), %rax
movq 0x28(%rax), %rax
movq %rax, -0x140(%rbp)
movl $0x38, %edi
callq 0x31c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x138(%rbp)
leaq 0xf508(%rip), %rax      # 0x13820
movq %rax, -0xb8(%rbp)
movq $0x0, -0xb0(%rbp)
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
leaq -0xa8(%rbp), %rcx
callq 0x5ae0
jmp 0x4346
movq -0x138(%rbp), %rdx
movq -0xd0(%rbp), %rsi
movq -0x140(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x43a7
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x28, %esi
callq 0x31d0
jmp 0x4470
movq -0x138(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x38, %esi
callq 0x31d0
jmp 0x4470
movq -0x10(%rbp), %rax
movl 0x20(%rax), %ecx
decl %ecx
movl %ecx, 0x20(%rax)
movl $0x38, %edi
callq 0x31c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x148(%rbp)
leaq -0x551(%rip), %rax      # 0x3e80
movq %rax, -0xc8(%rbp)
movq $0x0, -0xc0(%rbp)
movq -0xc8(%rbp), %rsi
movq -0xc0(%rbp), %rdx
leaq -0x10(%rbp), %rcx
callq 0x5ae0
jmp 0x43fc
movq -0x148(%rbp), %rdx
movq -0xd0(%rbp), %rsi
movq (%rsi), %rax
movq %rsi, %rdi
callq *0x48(%rax)
jmp 0x4467
movq -0x148(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x38, %esi
callq 0x31d0
jmp 0x4470
movq -0x10(%rbp), %rax
movq %rax, -0x150(%rbp)
cmpq $0x0, %rax
je 0x4456
movq -0x150(%rbp), %rdi
movl $0x28, %esi
callq 0x31d0
movq -0xd0(%rbp), %rdi
movl $0x1, %esi
callq 0x4b40
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x3330
nopl (%rax)