//
// commtool.c - Communications test tool
//
// (c)2013 Todd Shadburn <tshadburn@opencomputingsolutions.com>
//
//


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <cutil/cutil.h>
#include <comm/comm.h>


#ifndef win32
#define MODPATH "/usr/lib/comm/comm_tcp.so"
#else
#define MODPATH ".\\comm_tcp.dll"
#endif


#define	NET_BUFFER_SIZE	16384

int main (int argc, char **argv)
{
	int		rc;
	int		bytes;
	int		left;
	int		port;
	char		*host;
	char		*buffer = NULL;
	CommModule	*cm = NULL;
	CommChannel	*cc = NULL;
	CommChannel	*ccc = NULL;

	if (argc < 2) {
		fprintf (stderr, "Missing arguments.\n");
		fprintf (stderr,
			"Usage: commtool [client host port# bytes] | [server port#]\n");
		return 2;
	}


	buffer = calloc(1, NET_BUFFER_SIZE);
	if (buffer == NULL) {
		fprintf (stderr, "Failed to allocation network buffer.\n");
		return 2;
	}

	rc = comm_plugin_load(&cm, MODPATH, NULL);
	if (rc != 0) {
		fprintf (stderr, "comm_plugin_load(): failed. rc=%d\n", rc);
		return 2;
	}

	if (!strcmp (argv[1], "server")) {
		if (argc != 3) {
			fprintf (stderr, "Missing arguments for 'server'.\n");
			fprintf (stderr, "Usage:\n");
			fprintf (stderr, "commtool server port#\n");
			return 2;
		}
		port = atoi(argv[2]);
		fprintf (stderr, "port=%d\n", port);
		rc = comm_bind (cm, &cc, NULL, port);
		if (rc != 0) {
			fprintf (stderr, "comm_bind(): failed. rc=%d\n", rc);
			return 2;
		}

		while (1) {
			rc = comm_accept (cc, &ccc, 0);
			if (rc != 0) {
				fprintf (stderr, "comm_accept(): failed. rc=%d\n", rc);
				return 2;
			}
			fprintf (stdout, "Accepted connection, reading data...\n");
			while (1) {
				bytes = NET_BUFFER_SIZE;
				rc = comm_read (ccc, buffer, &bytes);
				if (rc != 0) {
					fprintf (stderr, "comm_read(): failed. rc=%d\n", rc);
					break;
				}
			}
			comm_close (&ccc, 0);
			ccc = NULL;
			fprintf (stdout, "Closed connection.\n");
		}

	} else if (!strcmp (argv[1], "client")) {

		if (argc != 5) {
			fprintf (stderr, "Missing arguments for 'client'.\n");
			fprintf (stderr, "Usage:\n");
			fprintf (stderr, "commtool client host port# bytes-to-send\n");
			return 2;
		}
		host = argv[2];
		port = atoi(argv[3]);
		rc = comm_connect (cm, &ccc, host, port);
		if (rc != 0) {
			fprintf (stderr, "comm_connect(): failed. rc=%d\n", rc);
			return 2;
		}
		fprintf (stdout, "Connected, sending data...\n");
		left = atoi(argv[4]);
		while (left > 0) {
			bytes = NET_BUFFER_SIZE;
			rc = comm_write (ccc, buffer, &bytes);
			if (rc != 0) {
				fprintf (stderr, "comm_write(): failed. rc=%d\n", rc);
				break;
			}
			left -= bytes;
		}

		comm_close (&ccc, 0);
		ccc = NULL;
		fprintf (stdout, "Closed connection.\n");

	} else {
		fprintf (stderr,
			"Invalid argument, 'client' or 'server' expected.\n");
		return 2;
	}

	return 0;
}


