#include <iostream>
#include <mpi.h>
#include <unistd.h>
using namespace std;

int main(int argc, char** argv){
	MPI_Init(&argc, &argv);
	int world_size, world_rank;
	MPI_Comm_size(MPI_COMM_WORLD, &world_size);
	MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
	if(world_size<2){
		if(world_rank==0){
			cerr<<"ERROR: Use -np 2"<<endl;
			MPI_Finalize();
			return 1;
		}
	}
	MPI_Request request;
	if(world_rank==0){
		int secret_code=420042;
		cout<<"[NODE 0] Boss is busy doing heavy calculations for 3 seconds..."<<endl;
		sleep(3);
		cout<<"[NODE 0] Calculations done. Firing message asynchronously!"<<endl;
		MPI_Isend(&secret_code, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);
		MPI_Wait(&request, MPI_STATUS_IGNORE);
		cout<<"[NODE 0] Boss signing off."<<endl;
	}
	else if(world_rank==1){
		int received_code=0;
		int message_arrived=0;
		cout<<"  ->[NODE 1] Worker opening mailbox asychronously..."<<endl;
		MPI_Irecv(&received_code, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);
		while(!message_arrived){
			cout<<"  ->[NODE 1] Mail has not arrived yet. Doing other useful math..."<<endl;
			sleep(1);
			MPI_Test(&request, &message_arrived, MPI_STATUS_IGNORE);
		}
		cout<<"  ->[NODE 1] DING! Message secured! The code is: "<<received_code<<endl;
		cout<<"  ->[NODE 1] Worker is signing off."<<endl;
	}
	MPI_Finalize();
	return 0;
}
