// File: luisremis[P]SDFS/Membership.cpp
// Function: Membership::detectThread()
void Membership::detectThread()
{
    /*
    WHILE LOOP
        roundId++

        randomly select one node
        send ping message
        sleep(1)
        see msgQueue, search ack
        if(ack)
            cout<<alive
            sleep(4)
            continue
        
        send ping message to random K nodes (call spreadMessage())
        sleep(4)
        see msgQueue, search ack
        if(ack)
            cout<<alive
            continue
        
        if(!ack)
            cout<<fail
            delete node
            send fail message to other nodes
            continue
    */
    bool flagFail = false;
    Node failedNode;
    while(!killDetectingThread)
    {
  
        roundId = (roundId+1)%255;

        if (roundId % 5 == 0)
        {
        	checkLeader();
        }

        logFile<< std::endl << "Detection Thread - Round: "<< roundId << " ------------" << std::endl;
        logFile<<printMember();
        
        if(members.size() < 2)
        {
            usleep(5 * MAX_LATENCY);
            flagFail = false;
            continue;
        }

        int select = rand()%(members.size()-1) + 1;
        Node theNode = members[select];

        if (flagFail == true)
        {
            theNode = failedNode;
        }

        Message msg;
        msg.type = MSG_PING;
        msg.TTL = 0;
        msg.roundId = roundId;
        ipString2Char4(theNode.ip_str, msg.carrierAdd);
        msg.timeStamp = 0;

        logFile<<"detectThread: checking alive or not for "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
        sendUDP(sockfd, theNode.ip_str, port, (char*)&msg, sizeof(Message));

        bool acked = false;

        if (queueSize() > 10){
            std::cout << "Warning!!! queueSize = " << queueSize() << std::endl;
        }

        usleep(MAX_LATENCY);

        msgQueueLock.lock();
        acked = ackMsgQueue();
        msgQueueLock.unlock();

        static int count = 0;
        if(acked){
            logFile<<"detectThread: node alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
            flagFail = false;
            usleep(4 * MAX_LATENCY);     
            continue;       
        }

        logFile<<"Hey!!! Node "<<theNode.ip_str<<" did not respond the first time!" << std::endl;

        msg.type = MSG_PIGGY;
        msg.TTL = 0;
        spreadMessage(msg,3);
        usleep(4 * MAX_LATENCY);

        msgQueueLock.lock();
        acked = ackMsgQueue();
        msgQueueLock.unlock();

        if(acked){
            logFile<<"detectThread: second round found node alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
            flagFail = false;
            continue;
        }
        else{
            logFile<< "detectThread: No ack received: node failed: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
            
            if (flagFail == true)
            {
                logFile<< "detectThread: No ack received: node failed: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
                failMember(theNode.ip_str, theNode.timeStamp);

                Message failMsg;
                failMsg.type = MSG_FAIL;
                failMsg.roundId = roundId;
                ipString2Char4(theNode.ip_str, failMsg.carrierAdd);
                failMsg.timeStamp = theNode.timeStamp;
                failMsg.TTL = 3;

                spreadMessage(failMsg);
                flagFail = false;
            }
            else
            {
                logFile<< "detectThread: Robust 2: It is alive: "<<theNode.ip_str<<" "<<theNode.timeStamp<<std::endl;
                failedNode = theNode;
                flagFail = true;

            }


            continue;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x168(%rbp)
movb $0x0, -0x9(%rbp)
leaq -0x38(%rbp), %rdi
callq 0xb570
movq -0x168(%rbp), %rax
movb 0x351(%rax), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x76ff
jmp 0x805b
movq -0x168(%rbp), %rax
movl 0x2c8(%rax), %eax
addl $0x1, %eax
movl $0xff, %ecx
cltd
idivl %ecx
movq -0x168(%rbp), %rax
movl %edx, 0x2c8(%rax)
movl 0x2c8(%rax), %eax
movl $0x5, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x7758
movq -0x168(%rbp), %rdi
callq 0xa380
jmp 0x7745
jmp 0x7758
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x806d
movq -0x168(%rbp), %rdi
movq 0x1f842(%rip), %rsi     # 0x26fa8
callq 0x4410
movq %rax, -0x170(%rbp)
jmp 0x7774
movq -0x170(%rbp), %rdi
leaq 0x14e9d(%rip), %rsi     # 0x1c61f
callq 0x43f0
movq %rax, -0x178(%rbp)
jmp 0x7790
movq -0x178(%rbp), %rdi
movq -0x168(%rbp), %rax
movl 0x2c8(%rax), %esi
callq 0x4670
movq %rax, -0x180(%rbp)
jmp 0x77b2
movq -0x180(%rbp), %rdi
leaq 0x14e7a(%rip), %rsi     # 0x1c63a
callq 0x43f0
movq %rax, -0x188(%rbp)
jmp 0x77ce
movq -0x188(%rbp), %rdi
movq 0x1f7cc(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x77e3
movq -0x168(%rbp), %rsi
movq %rsi, %rax
movq %rax, -0x190(%rbp)
leaq -0x68(%rbp), %rdi
callq 0xa4a0
jmp 0x77ff
movq -0x190(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x4370
jmp 0x7811
leaq -0x68(%rbp), %rdi
callq 0x42a0
movq -0x168(%rbp), %rdi
addq $0x258, %rdi            # imm = 0x258
callq 0xb990
cmpq $0x2, %rax
jae 0x7862
movl $0xf4240, %edi          # imm = 0xF4240
callq 0x4540
jmp 0x783f
movb $0x0, -0x9(%rbp)
jmp 0x76e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x42a0
jmp 0x806d
callq 0x4130
movq -0x168(%rbp), %rdi
cltq
movq %rax, -0x198(%rbp)
addq $0x258, %rdi            # imm = 0x258
movq %rdi, -0x1a0(%rbp)
callq 0xb990
movq -0x1a0(%rbp), %rdi
movq %rax, %rcx
movq -0x198(%rbp), %rax
decq %rcx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
incl %eax
movl %eax, -0x6c(%rbp)
movslq -0x6c(%rbp), %rsi
callq 0xb8d0
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
callq 0xb8f0
jmp 0x78c4
movb -0x9(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x78f6
leaq -0x98(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xbbd0
jmp 0x78e3
jmp 0x78f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x804d
movq -0x168(%rbp), %rax
movl $0x0, -0xac(%rbp)
movb $0x0, -0x9c(%rbp)
movb 0x2c8(%rax), %al
movb %al, -0xa8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x41e0
jmp 0x792f
leaq -0xa7(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x1a2b0
jmp 0x7944
leaq -0xd0(%rbp), %rdi
callq 0x42a0
movq -0x168(%rbp), %rdi
movl $0x0, -0xa0(%rbp)
leaq 0x14ce0(%rip), %rsi     # 0x1c648
callq 0x43f0
movq %rax, -0x1a8(%rbp)
jmp 0x7976
movq -0x1a8(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x1b0(%rbp)
jmp 0x7992
movq -0x1b0(%rbp), %rdi
leaq 0x14982(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x1b8(%rbp)
jmp 0x79ae
movq -0x1b8(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x1c0(%rbp)
jmp 0x79c6
movq -0x1c0(%rbp), %rdi
movq 0x1f5d4(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x79db
movq -0x168(%rbp), %rax
movl 0x298(%rax), %edx
movl 0x29c(%rax), %edi
leaq -0x98(%rbp), %rsi
leaq -0xac(%rbp), %rcx
movl $0x14, %r8d
callq 0x1a870
jmp 0x7a09
movq -0x168(%rbp), %rdi
movb $0x0, -0xd1(%rbp)
callq 0xa6f0
movl %eax, -0x1c4(%rbp)
jmp 0x7a24
movl -0x1c4(%rbp), %eax
cmpl $0xa, %eax
jle 0x7aae
movq 0x1f58a(%rip), %rdi     # 0x26fc0
leaq 0x14c34(%rip), %rsi     # 0x1c671
callq 0x43f0
movq %rax, -0x1d0(%rbp)
jmp 0x7a4b
movq -0x168(%rbp), %rdi
callq 0xa6f0
movl %eax, -0x1d4(%rbp)
jmp 0x7a5f
movl -0x1d4(%rbp), %esi
movq -0x1d0(%rbp), %rdi
callq 0x4670
movq %rax, -0x1e0(%rbp)
jmp 0x7a7a
movq -0x1e0(%rbp), %rdi
movq 0x1f520(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7a8f
jmp 0x7aae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x42a0
jmp 0x804d
movl $0x30d40, %edi          # imm = 0x30D40
callq 0x4540
jmp 0x7aba
movq -0x168(%rbp), %rdi
addq $0x310, %rdi            # imm = 0x310
callq 0xb5f0
jmp 0x7acf
movq -0x168(%rbp), %rdi
callq 0xa720
movb %al, -0x1e1(%rbp)
jmp 0x7ae3
movq -0x168(%rbp), %rdi
movb -0x1e1(%rbp), %al
andb $0x1, %al
movb %al, -0xd1(%rbp)
addq $0x310, %rdi            # imm = 0x310
callq 0xb620
jmp 0x7b06
testb $0x1, -0xd1(%rbp)
je 0x7bb3
movq -0x168(%rbp), %rdi
leaq 0x14b68(%rip), %rsi     # 0x1c689
callq 0x43f0
movq %rax, -0x1f0(%rbp)
jmp 0x7b2f
movq -0x1f0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x1f8(%rbp)
jmp 0x7b4b
movq -0x1f8(%rbp), %rdi
leaq 0x147c9(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x200(%rbp)
jmp 0x7b67
movq -0x200(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x208(%rbp)
jmp 0x7b7f
movq -0x208(%rbp), %rdi
movq 0x1f41b(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7b94
movb $0x0, -0x9(%rbp)
movl $0xc3500, %edi          # imm = 0xC3500
callq 0x4540
jmp 0x7ba4
movl $0x2, -0xd8(%rbp)
jmp 0x803c
movq -0x168(%rbp), %rdi
leaq 0x14ae3(%rip), %rsi     # 0x1c6a4
callq 0x43f0
movq %rax, -0x210(%rbp)
jmp 0x7bcf
movq -0x210(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x218(%rbp)
jmp 0x7beb
movq -0x218(%rbp), %rdi
leaq 0x14ab8(%rip), %rsi     # 0x1c6b1
callq 0x43f0
movq %rax, -0x220(%rbp)
jmp 0x7c07
movq -0x220(%rbp), %rdi
movq 0x1f393(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7c1c
movq -0x168(%rbp), %rdi
movl $0x2, -0xac(%rbp)
movb $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
movl %eax, -0xe0(%rbp)
movups -0xac(%rbp), %xmm0
movaps %xmm0, -0xf0(%rbp)
movl -0xe0(%rbp), %ecx
movq %rsp, %rax
movl %ecx, 0x10(%rax)
movaps -0xf0(%rbp), %xmm0
movups %xmm0, (%rax)
movl $0x3, %esi
callq 0x8a90
jmp 0x7c70
movl $0xc3500, %edi          # imm = 0xC3500
callq 0x4540
jmp 0x7c7c
movq -0x168(%rbp), %rdi
addq $0x310, %rdi            # imm = 0x310
callq 0xb5f0
jmp 0x7c91
movq -0x168(%rbp), %rdi
callq 0xa720
movb %al, -0x221(%rbp)
jmp 0x7ca5
movq -0x168(%rbp), %rdi
movb -0x221(%rbp), %al
andb $0x1, %al
movb %al, -0xd1(%rbp)
addq $0x310, %rdi            # imm = 0x310
callq 0xb620
jmp 0x7cc8
testb $0x1, -0xd1(%rbp)
je 0x7d69
movq -0x168(%rbp), %rdi
leaq 0x149ef(%rip), %rsi     # 0x1c6d2
callq 0x43f0
movq %rax, -0x230(%rbp)
jmp 0x7cf1
movq -0x230(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x238(%rbp)
jmp 0x7d0d
movq -0x238(%rbp), %rdi
leaq 0x14607(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x240(%rbp)
jmp 0x7d29
movq -0x240(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x248(%rbp)
jmp 0x7d41
movq -0x248(%rbp), %rdi
movq 0x1f259(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7d56
movb $0x0, -0x9(%rbp)
movl $0x2, -0xd8(%rbp)
jmp 0x803c
movq -0x168(%rbp), %rdi
leaq 0x14989(%rip), %rsi     # 0x1c700
callq 0x43f0
movq %rax, -0x250(%rbp)
jmp 0x7d85
movq -0x250(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x258(%rbp)
jmp 0x7da1
movq -0x258(%rbp), %rdi
leaq 0x14573(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x260(%rbp)
jmp 0x7dbd
movq -0x260(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x268(%rbp)
jmp 0x7dd5
movq -0x268(%rbp), %rdi
movq 0x1f1c5(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7dea
movb -0x9(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x7f9b
movq -0x168(%rbp), %rdi
leaq 0x148f7(%rip), %rsi     # 0x1c700
callq 0x43f0
movq %rax, -0x270(%rbp)
jmp 0x7e17
movq -0x270(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x278(%rbp)
jmp 0x7e33
movq -0x278(%rbp), %rdi
leaq 0x144e1(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x280(%rbp)
jmp 0x7e4f
movq -0x280(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x288(%rbp)
jmp 0x7e67
movq -0x288(%rbp), %rdi
movq 0x1f133(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x7e7c
leaq -0x110(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x41e0
jmp 0x7e91
movq -0x168(%rbp), %rdi
movl -0x78(%rbp), %edx
leaq -0x110(%rbp), %rsi
callq 0x8f40
jmp 0x7ea9
leaq -0x110(%rbp), %rdi
callq 0x42a0
movq -0x168(%rbp), %rax
movl $0x5, -0x124(%rbp)
movb 0x2c8(%rax), %al
movb %al, -0x120(%rbp)
leaq -0x148(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x41e0
jmp 0x7ee7
leaq -0x11f(%rbp), %rsi
leaq -0x148(%rbp), %rdi
callq 0x1a2b0
jmp 0x7efc
leaq -0x148(%rbp), %rdi
callq 0x42a0
movq -0x168(%rbp), %rdi
movl -0x78(%rbp), %eax
movl %eax, -0x118(%rbp)
movb $0x3, -0x114(%rbp)
movl -0x114(%rbp), %eax
movl %eax, -0x150(%rbp)
movups -0x124(%rbp), %xmm0
movaps %xmm0, -0x160(%rbp)
movl -0x150(%rbp), %ecx
movq %rsp, %rax
movl %ecx, 0x10(%rax)
movaps -0x160(%rbp), %xmm0
movups %xmm0, (%rax)
xorl %esi, %esi
callq 0x8a90
jmp 0x7f58
movb $0x0, -0x9(%rbp)
jmp 0x8032
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x42a0
jmp 0x804d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x42a0
jmp 0x804d
movq -0x168(%rbp), %rdi
leaq 0x14784(%rip), %rsi     # 0x1c72d
callq 0x43f0
movq %rax, -0x290(%rbp)
jmp 0x7fb7
movq -0x290(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4370
movq %rax, -0x298(%rbp)
jmp 0x7fd3
movq -0x298(%rbp), %rdi
leaq 0x14341(%rip), %rsi     # 0x1c322
callq 0x43f0
movq %rax, -0x2a0(%rbp)
jmp 0x7fef
movq -0x2a0(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x4670
movq %rax, -0x2a8(%rbp)
jmp 0x8007
movq -0x2a8(%rbp), %rdi
movq 0x1ef93(%rip), %rsi     # 0x26fa8
callq 0x4410
jmp 0x801c
leaq -0x38(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0xbbd0
jmp 0x802e
movb $0x1, -0x9(%rbp)
movl $0x2, -0xd8(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xb7f0
jmp 0x76e7
leaq -0x98(%rbp), %rdi
callq 0xb7f0
jmp 0x806d
leaq -0x38(%rbp), %rdi
callq 0xb7f0
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0xb7f0
movq -0x40(%rbp), %rdi
callq 0x46a0
nop