// Adapted from example code from Deino MPI
// http://mpi.deino.net/mpi_functions/MPI_Comm_accept.html

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main( int argc, char *argv[] )
{
    int num_errors = 0;
    int rank, size;
    char port1[MPI_MAX_PORT_NAME];
    MPI_Status status;
    MPI_Comm comm1;
    int data = 0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (size < 2)
    {
        printf("Two processes needed to run this test.\n");fflush(stdout);
        MPI_Finalize();
        return 0;
    }

    if (rank == 0)
    {
        printf("0: opening ports.\n");fflush(stdout);
        MPI_Open_port(MPI_INFO_NULL, port1);
        printf("opened port1: <%s>\n", port1);

        MPI_Send(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);

        printf("accepting port1.\n");fflush(stdout);
        MPI_Comm_accept(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
        MPI_Close_port(port1);

        printf("sending 1 to process 1.\n");fflush(stdout);
        data = 1;
        MPI_Send(&data, 1, MPI_INT, 0, 0, comm1);

        MPI_Comm_disconnect(&comm1);
    }
    else if (rank == 1)
    {
        MPI_Recv(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
        MPI_Comm_connect(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
        MPI_Recv(&data, 1, MPI_INT, 0, 0, comm1, &status);
        if (data != 1)
        {
            printf("Received %d from root when expecting 1\n", data);
            fflush(stdout);
            num_errors++;
        }
        MPI_Comm_disconnect(&comm1);

        printf("Rank %d: just before sleep\n", rank);
        printf("sleeping...\n");
        sleep(5);
        printf("Rank %d: just after sleep\n", rank);
    }

    printf("Rank %d: just before finalize\n", rank);
    MPI_Finalize();
    printf("Rank %d: just after finalize\n", rank);
    return 0;
}
