/*
** Simple test program 02 for the MIAMI protocol
** Rolf Riesen, December 2009
**
** Usage: test_02b local_host local_port remote_host remote_port rank
** rank should be 0 in one process, and 1 in the other.
**
** Let's do ping-pong! (short version)
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#if defined (_MPI_)
#include <mpi.h>
#endif
#include "miami.h"

#define BUF_SIZE	(6)



int
main(int argc, char *argv[])
{

char *host1;
char *host2;
int sbuf[BUF_SIZE];
int rbuf[BUF_SIZE];
int port1, port2;
int rank;
int tag;
int shandle, rhandle;
int bytes;
int i;
int flag;
int rc= 0;


    if (argc != 6)   {
	fprintf(stderr, "Usage: %s local_host local_port remote_host remote_port rank\n", argv[0]);
	return -1;
    }

    host1= argv[1];
    host2= argv[3];
    port1= strtol(argv[2], NULL, 10);
    port2= strtol(argv[4], NULL, 10);
    rank= strtol(argv[5], NULL, 10);

    printf("Test I'm running on host %s, rank %d and will connect to host %s, port %d\n", host1, rank, host2, port2);

    miami_init(host1, port1, host2, port2);
#if defined (_MPI_)
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif

    tag= 12;

    if (rank == 0)   {
	/* I'm the sender */

	/* Fill the send buffer */
	for (i= 0; i < BUF_SIZE; i++)   {
	    sbuf[i]= i;
	}

	/* Post the receive buffer so it is ready for the reply */
	rhandle= miami_rx_start(rbuf, sizeof(int) * BUF_SIZE, tag);

	/* Send the data */
	shandle= miami_tx_start(sbuf, sizeof(int) * BUF_SIZE, tag);

	while (!miami_rx_done(rhandle, &bytes))   {
	    /* Wait for the message to come back*/
	}

	if (sizeof(int) * BUF_SIZE != bytes)   {
	    printf("ERROR: Sent %d and received %d bytes\n", (int)sizeof(int) * BUF_SIZE, bytes);
	    rc= 1;
	}

	/* Check the receive buffer against the send buffer */
	flag= 1;
	for (i= 0; i < (bytes / (int)sizeof(int)); i++)   {
	    if (rbuf[i] != sbuf[i])   {
		fprintf(stderr, "ERROR: Send and recv buffer differ at position %d: %d != %d\n", i, rbuf[i], sbuf[i]);
		flag= 0;
		rc= 1;
		break;
	    }
	}

	/* Clean up resources */
	while (!miami_tx_done(shandle))   {
	    /* This should return immediately, since the send is long done */
	}

	if (flag)   {
	    printf("Test Message ping-pong worked!\n");
	} else   {
	    printf("Test Message ping-pong did NOT work!\n");
	}

    } else   {

	/* I'm the receiver */

	/* Clear the receive buffer */
	memset(rbuf, 0, sizeof(int) * BUF_SIZE);

	/* Post a receive */
	rhandle= miami_rx_start(rbuf, sizeof(int) * BUF_SIZE, tag);
	while (!miami_rx_done(rhandle, &bytes))   {
	    /* Wait for that message */
	}
	printf("Received %d bytes\n", bytes);
	if (bytes != sizeof(int) * BUF_SIZE)   {
	    printf("ERROR: received %d bytes, expected %d\n", bytes, (int)sizeof(int) * BUF_SIZE);
	    rc= 1;
	}

	for (i= 0; i < bytes / (int)sizeof(int); i++)   {
	    printf("%d\n", rbuf[i]);
	}

	/* Send the amount of data we received back */
	shandle= miami_tx_start(rbuf, bytes, tag);
	while (!miami_tx_done(shandle))   {
	    /* We have to make sure the protocol has a chance to send the buffer */
	}
    }

    miami_finalize();

    return rc;

}  /* end of main() */
