// File: zkl94[P]distributed-key-value-store/MP1Node.cpp
// Function: MP1Node::introduceSelfToGroup(Address*)
int MP1Node::introduceSelfToGroup(Address *joinaddr) {
    MessageHdr *msg;
#ifdef DEBUGLOG
    static char s[1024];
#endif

    if ( 0 == memcmp((char *)&(memberNode->addr.addr), (char *)&(joinaddr->addr), sizeof(memberNode->addr.addr))) {
        // I am the group booter (first process to join the group). Boot up the group
#ifdef DEBUGLOG
        log->LOG(&memberNode->addr, "Starting up group...");
#endif
        memberNode->inGroup = true;
    }
    else {

        // member node in group only after receiving JOINREP

        size_t msgsize = sizeof(MessageHdr) + sizeof(joinaddr->addr) + sizeof(long);
        msg = (MessageHdr *) malloc(msgsize * sizeof(char));

        // create JOINREQ message: format of data is {struct Address myaddr}
        msg->msgType = JOINREQ;
        memcpy((char *)(msg+1), &memberNode->addr.addr, sizeof(memberNode->addr.addr));
        memcpy((char *)(msg+1) + sizeof(memberNode->addr.addr), &memberNode->heartbeat, sizeof(long));

#ifdef DEBUGLOG
        sprintf(s, "Trying to join...");
        log->LOG(&memberNode->addr, s);
#endif

        // send JOINREQ message to introducer member
        emulNet->ENsend(&memberNode->addr, joinaddr, (char *)msg, msgsize);

        free(msg);
    }

    // add self to memberlist; self is ALWAYS the first member
    int id = 0;
    short port;
    memcpy(&id, &(memberNode->addr.addr[0]), sizeof(int));
    memcpy(&port, &(memberNode->addr.addr[4]), sizeof(short));
    MemberListEntry *newEntry = new MemberListEntry(id, port, 0, par->getcurrtime());
    memberNode->memberList.push_back(*newEntry);

    return 1;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq 0x20(%rax), %rdi
addq $0x8, %rdi
movq -0x10(%rbp), %rsi
movl $0x6, %edx
callq 0x4170
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x4da4
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movb $0x1, 0xf(%rax)
jmp 0x4e1d
movq $0x12, -0x20(%rbp)
movq -0x20(%rbp), %rdi
shlq $0x0, %rdi
callq 0x4440
movq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, -0x18(%rbp)
movq -0x18(%rbp), %rcx
movl $0x0, (%rcx)
movq -0x18(%rbp), %rcx
movq 0x20(%rax), %rdx
movl 0x8(%rdx), %esi
movl %esi, 0x4(%rcx)
movw 0xc(%rdx), %dx
movw %dx, 0x8(%rcx)
movq -0x18(%rbp), %rcx
movq 0x20(%rax), %rdx
movq 0x18(%rdx), %rdx
movq %rdx, 0xa(%rcx)
movq 0x8(%rax), %rdi
movq 0x20(%rax), %rsi
addq $0x8, %rsi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
movq -0x20(%rbp), %rax
movl %eax, %r8d
callq 0xac80
movq -0x18(%rbp), %rdi
callq 0x43e0
movq -0x48(%rbp), %rax
movl $0x0, -0x24(%rbp)
movq 0x20(%rax), %rcx
movl 0x8(%rcx), %ecx
movl %ecx, -0x24(%rbp)
movq 0x20(%rax), %rax
movw 0xc(%rax), %ax
movw %ax, -0x26(%rbp)
movl $0x18, %edi
callq 0x4310
movq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, -0x60(%rbp)
movl -0x24(%rbp), %ecx
movl %ecx, -0x54(%rbp)
movw -0x26(%rbp), %cx
movw %cx, -0x4e(%rbp)
movq 0x18(%rax), %rdi
callq 0x15020
movl %eax, -0x4c(%rbp)
jmp 0x4e6f
movl -0x54(%rbp), %esi
movq -0x60(%rbp), %rdi
movw -0x4e(%rbp), %ax
movl -0x4c(%rbp), %ecx
movslq %ecx, %r8
movswl %ax, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x15110
jmp 0x4e8e
movq -0x48(%rbp), %rax
movq -0x60(%rbp), %rcx
movq %rcx, -0x30(%rbp)
movq 0x20(%rax), %rdi
addq $0x28, %rdi
movq -0x30(%rbp), %rsi
callq 0x6da0
movl $0x1, %eax
addq $0x60, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movl $0x18, %esi
callq 0x4320
movq -0x38(%rbp), %rdi
callq 0x4550
nopl (%rax)