#include <iostream>
#include <mpi.h>
#include <stdlib.h>

using namespace std;

// This expects intracom size and the port name to connect to.
// When using with shell, use single quotas to avoid shell substitution.
int main(int argc, char** argv)
{

    int ac = 0;
    MPI_Init(&ac, &argv);

    int np = atoi(argv[1]);
    char portName[MPI_MAX_PORT_NAME];

    MPI_Comm intercomm, intracomm;

    MPI_Lookup_name("my_service", MPI_INFO_NULL, portName);
    cout << "Connecting to " << portName << "\n";

    MPI_Comm_connect(portName, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm);

    cout << "Connected.\n";

    MPI_Intercomm_merge(intercomm, true, &intracomm);

    cout << "Merged.\n";

    MPI_Comm_free(&intercomm);

    int i;

    MPI_Comm_size(intracomm, &i);

    // Build an intracom dynamically until n processes are reached.
    for (; i < np; i++) {

        MPI_Comm_accept(portName, MPI_INFO_NULL, 0, intracomm, &intercomm);

        cout << "Accepted.\n";

        MPI_Intercomm_merge(intercomm, false, &intracomm);

        cout << "Merged to an intracom.\n";

        MPI_Comm_free(&intercomm);
    }

    // Intracomm contains the one we can now use with n-grid.
    MPI_Comm_free(&intracomm);

    MPI_Finalize();
}
