// File: /workspace/github_cpp_makefile_star2_O3/sidscrazy[P]Paxos/paxos_node.cpp
// Function: PaxosNode::process_message(message*)
void process_message (message *m){
		if (m == NULL){
			return;
		}

		int reponse_code; 
		switch (m->type){
			case MSG_PREPARE: {
				if (m->round > n) {
					n = m->round;
				} 
				state = PREPARING;
				message response (id, m->sender, v, n, MSG_PREPARE_ACK);
				network_lock.lock ();
				send_message (0, &response);
				network_lock.unlock ();
				break; 
			}

			case MSG_PREPARE_ACK: {

				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				} else if (m->round == n){
					bool already_voted = false;
					for (int i = 0; i < prepare_acks.size (); i++){
						if (prepare_acks [i] == m->sender){
							already_voted = true;
							break;
						}
					}
					if (!already_voted){
						prepare_acks.push_back (m->sender);
						if (v < m->value && !proposed_v){
							v = m->value;
						}
					}

				} else {
					message response (id, m->sender, NO_VALUE, n, MSG_UPDATE);
					network_lock.lock ();
					send_message (0, &response);
					network_lock.unlock ();
					 
				}
				break;
			}

			case MSG_PROPOSE: {
				if (m->round == n && state == PREPARING &&
					((m->value >= v && !proposed_v) || (m->value == v && proposed_v)) ){
					v = m->value;
					state = PROPOSING;
					proposed_v = true;
				} 
				message response (id, m->sender, v, n, MSG_PROPOSE_ACK);
				network_lock.lock ();
				send_message (0, &response);
				network_lock.unlock ();
				break;
			}

			case MSG_PROPOSE_ACK: {
				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				} else if (m->round < n){
					message response (id, m->sender, NO_VALUE, n, MSG_UPDATE);
					network_lock.lock ();
					send_message (0, &response);
					network_lock.unlock ();

				} else {
					vote *vo = (vote *) malloc (sizeof (vote));
					vo->node = m->sender;
					vo->n = m->round;
					vo->v = m->value;
					votes.push_back (vo);
				} 
				break;
			}

			case MSG_UPDATE: {
				if (m->round > n){
					n = m->round;
					state = NO_VALUE;
					clear_responses ();
				}
				break; 
			}

			case MSG_CONSENSUS: {
				safe_exit (m);
				break;
			}

			case MSG_TEARDOWN: {
				safe_exit (m);
				break;
			}

			default: 
				break;
		}

		free (m);
		if (!(role & PROPOSER)){
			simulate_crash ();
		}
		
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
testq %rsi, %rsi
je 0x2e95
movq %rsi, %r14
movq %rdi, %rbx
movl 0x10(%rsi), %eax
decl %eax
cmpl $0x7, %eax
ja 0x2e7f
leaq 0x233f(%rip), %rcx      # 0x5004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
movq %r14, %rsi
callq 0x37fc
jmp 0x2e7f
movl 0xc(%r14), %ecx
movl 0x10(%rbx), %eax
cmpl %eax, %ecx
jle 0x2de0
movl %ecx, 0x10(%rbx)
jmp 0x2dcc
movl 0xc(%r14), %ecx
movl 0x10(%rbx), %eax
cmpl %eax, %ecx
jle 0x2d05
movl %ecx, 0x10(%rbx)
movl %ecx, %eax
movl $0xfffffffc, 0x14(%rbx) # imm = 0xFFFFFFFC
movl (%r14), %ecx
movl (%rbx), %edx
movl 0xc(%rbx), %esi
movl %edx, -0x40(%rbp)
movl %ecx, -0x3c(%rbp)
movl %esi, -0x38(%rbp)
movl %eax, -0x34(%rbp)
movl $0x2, -0x30(%rbp)
jmp 0x2d7c
movl 0x10(%rbx), %eax
cmpl %eax, 0xc(%r14)
jne 0x2d61
cmpl $-0x4, 0x14(%rbx)
jne 0x2d61
movl 0x8(%r14), %ecx
movl 0xc(%rbx), %edx
cmpl %edx, %ecx
jl 0x2d49
cmpb $0x1, 0x18(%rbx)
jne 0x2d53
cmpl %edx, %ecx
jne 0x2d61
cmpb $0x1, 0x18(%rbx)
jne 0x2d61
movl %ecx, 0xc(%rbx)
movl $0xfffffffb, 0x14(%rbx) # imm = 0xFFFFFFFB
movb $0x1, 0x18(%rbx)
movl (%r14), %ecx
movl (%rbx), %edx
movl 0xc(%rbx), %esi
movl %edx, -0x40(%rbp)
movl %ecx, -0x3c(%rbp)
movl %esi, -0x38(%rbp)
movl %eax, -0x34(%rbp)
movl $0x4, -0x30(%rbp)
leaq 0x28(%rbx), %r15
movq %r15, %rdi
callq 0x22b0
testl %eax, %eax
jne 0x2ef4
leaq -0x40(%rbp), %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x33b2
movq %r15, %rdi
jmp 0x2e7a
movl 0xc(%r14), %r15d
movl 0x10(%rbx), %eax
cmpl %eax, %r15d
jle 0x2e38
movl %r15d, 0x10(%rbx)
jmp 0x2dcc
movl 0xc(%r14), %eax
cmpl 0x10(%rbx), %eax
jle 0x2e7f
movl %eax, 0x10(%rbx)
movl $0xffffffff, 0x14(%rbx) # imm = 0xFFFFFFFF
movq %rbx, %rdi
callq 0x375a
jmp 0x2e7f
jne 0x2e3a
movq 0xe0(%rbx), %rax
movq 0xe8(%rbx), %rsi
movq %rsi, %rcx
subq %rax, %rcx
je 0x2e16
sarq $0x2, %rcx
movl (%r14), %edx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edi, %edi
cmpl %edx, (%rax,%rdi,4)
je 0x2e7f
incq %rdi
cmpq %rdi, %rcx
jne 0x2e09
cmpq 0xf0(%rbx), %rsi
je 0x2ed1
movl (%r14), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0xe8(%rbx)
jmp 0x2ee0
jge 0x2ea2
movl (%rbx), %ecx
movl (%r14), %edx
leaq -0x40(%rbp), %r15
movl %ecx, (%r15)
movl %edx, 0x4(%r15)
movl $0xffffffff, 0x8(%r15)  # imm = 0xFFFFFFFF
movl %eax, 0xc(%r15)
movl $0x5, 0x10(%r15)
leaq 0x28(%rbx), %r12
movq %r12, %rdi
callq 0x2c72
movq %rbx, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x33b2
movq %r12, %rdi
callq 0x2160
movq %r14, %rdi
callq 0x2240
testb $0x1, 0x8(%rbx)
jne 0x2e95
movq %rbx, %rdi
callq 0x3866
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl $0xc, %edi
callq 0x2280
leaq -0x40(%rbp), %rsi
movq %rax, (%rsi)
movl (%r14), %ecx
movl %ecx, (%rax)
movl %r15d, 0x4(%rax)
movl 0x8(%r14), %ecx
movl %ecx, 0x8(%rax)
leaq 0xc8(%rbx), %rdi
callq 0x37d8
jmp 0x2e7f
leaq 0xe0(%rbx), %rdi
movq %r14, %rdx
callq 0x3afc
movl 0x8(%r14), %eax
cmpl %eax, 0xc(%rbx)
jge 0x2e7f
cmpb $0x0, 0x18(%rbx)
jne 0x2e7f
movl %eax, 0xc(%rbx)
jmp 0x2e7f
movl %eax, %edi
callq 0x2120
nop