/*
** Simple test program 02 for the MIAMI protocol
** Rolf Riesen, December 2009
**
** Usage: test_07 local_host local_port remote_host remote_port rank
** rank should be 0 in one process, and 1 in the other.
**
** Another tag test
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#if defined (_MPI_)
#include <mpi.h>
#endif
#include "miami.h"

#define NUM_MSG		(10)



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

char *host1;
char *host2;
int sbuf[NUM_MSG];
int rbuf[NUM_MSG];
int port1, port2;
int rank;
int shandle[NUM_MSG], rhandle[NUM_MSG];
int bytes;
int i;
int expected;
int flag;
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

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

	sbuf[0]= 999999;
	shandle[0]= miami_tx_start(&sbuf[0], sizeof(int), 999999);
	printf("Test Tag test: Sending message with tag %d, sbuf %d\n", 999999, sbuf[0]);

	/* Send the data */
	for (i= 1; i < NUM_MSG; i++)   {
	    sbuf[i]= 100 + i;
	    shandle[i]= miami_tx_start(&sbuf[i], sizeof(int), i);
	    printf("Tag test: Sending message with tag %d, sbuf %d\n", i, sbuf[i]);
	}
	printf("Test Tag 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 Tag test: Sends have completed\n");

    } else   {

	/* I'm the receiver */

	flag= 0;
	for (i= 1; i < NUM_MSG; i++)   {
	    /* Post a receive */
	    rbuf[i]= 0;
	    /* Receive them in inverse tag order */
	    rhandle[i]= miami_rx_start(&rbuf[i], sizeof(int), i);
	}
	rhandle[0]= miami_rx_start(&rbuf[0], sizeof(int), 999999);


	for (i= 1; i < NUM_MSG; i++)   {
	    while (!miami_rx_done(rhandle[i], &bytes))   {
	    }
	    printf("Test Tag test: Received message %d (tag %d) with %d bytes, rbuf %d\n",
		i, NUM_MSG - i - 1, bytes, rbuf[i]);

	    expected= 100 + i;
	    if (rbuf[i] != expected)   {
		printf("ERROR: Expected %d, but got %d in message %d\n",
		    expected, rbuf[i], i);
		flag= 1;
		rc= 1;
	    }
	}

	/* Pick up the first one */
	while (!miami_rx_done(rhandle[0], &bytes))   {
	}
	printf("Test Tag test: Received message %d (tag %d) with %d bytes, rbuf %d\n",
	    0, NUM_MSG - 0 - 1, bytes, rbuf[0]);

	expected= 999999;
	if (rbuf[0] != expected)   {
	    printf("ERROR: Expected %d, but got %d in message %d\n",
		expected, rbuf[0], 0);
	    flag= 1;
	    rc= 1;
	}

	if (flag)   {
	    printf("Test Tag test: Done ERROR\n");
	} else   {
	    printf("Test Tag test: Done OK\n");
	}
    }

    miami_finalize();

    return rc;

}  /* end of main() */
