/*
** Simple test program 02 for the MIAMI protocol
** Rolf Riesen, December 2009
**
** Usage: test_05 local_host local_port remote_host remote_port rank
** rank should be 0 in one process, and 1 in the other.
**
** Send a bunch of messages back and forth
*/
#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	(16)
#define NUM_MSG		(10)



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[NUM_MSG], rhandle;
int bytes;
int i, j;
int ack, cmp;
int rc;


    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);

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

    tag= 12;
    rc= 0;

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

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

	/* Post the receive buffer so it is ready for the reply */
	ack= 0;
	rhandle= miami_rx_start(&ack, sizeof(int), tag);
	printf("Test Msg flood test: Post receive for ACK\n");

	/* Send the data */
	for (i= 0; i < NUM_MSG; i++)   {
	    shandle[i]= miami_tx_start(sbuf, sizeof(int) * BUF_SIZE, tag);
	}
	printf("Test Msg flood test: Sent %d messages\n", NUM_MSG);

	/* Wait for them to finish */
	for (i= 0; i < NUM_MSG; i++)   {
	    while (!miami_tx_done(shandle[i]))   {
	    }
	}

	printf("Test Msg flood test: Waiting for ACK\n");
	/* Wait for the ACK */
	while (!miami_rx_done(rhandle, &bytes))   {
	}
	if (ack == cmp)   {
	    printf("Test Msg flood test succeeded\n");
	    rc= 0;
	} else   {
	    printf("ERROR: Msg flood test failed: ack %d, cmp %d\n", ack, cmp);
	    rc= 1;
	}

    } else   {

	/* I'm the receiver */

	ack= 0;
	for (i= 0; i < NUM_MSG; i++)   {
	    /* 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("Test Msg flood test: Received message %d with %d bytes\n", i, bytes);

	    /* Check the receive buffer */
	    for (j= 0; j < (bytes / (int)sizeof(int)); j++)   {
		ack= ack + rbuf[j];
	    }

	}

	/* Send an ACK back */
	printf("Test Msg flood test: Sending ACK %d\n", ack);
	shandle[0]= miami_tx_start(&ack, sizeof(int), tag);
	while (!miami_tx_done(shandle[0]))   {
	}
	printf("Test Msg flood test: ACK Sent\n");
    }

    miami_finalize();

    return rc;

}  /* end of main() */
