/*
 *
 *   udpclient.cc
 *
 *   Implements a simple UDP RFC868 client.
 *
 *   Copyright (C) 2001 by Matt Roberts, KK5JY,
 *   All rights reserved.
 *
 *   TODO:
 *      + Add syslog support to make it all very pretty. :)
 *
 *
 */


#include <iostream>
#include <string>

#include <my++/muxudpsocket.h>
#include <my++/multiplex.h>
#include <sys/time.h>

/*
 *
 *   main (...)
 *
 */

int main (int argc, char **argv) {
	char host[128];
	const unsigned iterations = 1;

	if (argc > 1) {
		strncpy(host, argv[1], sizeof(host));
	} else {
		printf("Must specify hostname.\n");
		return 1;
	}

	my::multiplexed::udpsocket sock;
	my::multiplex mux;
	my::multiplexed::udpsocket::address remote (host, 37);
	my::multiplexed::udpsocket::address answer;

	std::string astr;
	char buffer [128];
	size_t count;

	mux.add(sock);


	for (size_t i = 0; i < 10; ++i) {
		try {
			count = sock.put_to (remote, "", 0);
		} catch (const std::exception &e) {
			std::cerr << "\'put_to\' error: " << e.what() << std::endl;
			return 1;
		}
	}

	for (size_t i = 0; i < iterations; ++i) {
		count = mux.watch();

		if ( (count > 0) && (sock.ready()) ) {
			try {
				count = sock.get_from (answer, buffer, sizeof(buffer));
			} catch (const std::exception &e) {
				std::cerr << "\'get_from\' error: " << e.what() << std::endl;
				return 1;
			}

			if (count == 4)
				std::cout << "Response from: " << answer.to_string() << ", " << count << " bytes" << std::endl;
			else {
				std::cerr << "Response from " << answer.to_string() << " was wrong length (" << count << " bytes)" << std::endl;
				return 1;
			}

			const uint32_t offset = 2208988800UL;      // 0000h GMT, Jan 1, 1970 / 100

			union {
				uint32_t my_long;
				char buffer[4];
			} uts;

			for (int i = 0; i < 4; ++i)
				uts.buffer[i] = buffer[i];

			uts.my_long = ntohl (uts.my_long); /* reorder the bytes in the word */
			uts.my_long -= offset;             /* offset to 1 Jan 1970          */
			time_t utc_time = uts.my_long;     /* convert to type time_t        */
			tm *utc_struct = gmtime (&utc_time);  /* get time associated with above */

			std::cout << "Current Unix time is:  " << utc_time << std::endl;
			snprintf (buffer, sizeof(buffer), "%02d/%02d/%04d %02d:%02d:%02d",
					(utc_struct->tm_mon + 1),
					utc_struct->tm_mday,
					(utc_struct->tm_year + 1900),
					utc_struct->tm_hour,
					utc_struct->tm_min,
					utc_struct->tm_sec);

			std::cout << "Current GMT time is:   " << buffer << std::endl;

			utc_struct = localtime (&utc_time);  /* get time associated with above */

			snprintf (buffer, sizeof(buffer), "%02d/%02d/%04d %02d:%02d:%02d",
					(utc_struct->tm_mon + 1),
					utc_struct->tm_mday,
					(utc_struct->tm_year + 1900),
					utc_struct->tm_hour,
					utc_struct->tm_min,
					utc_struct->tm_sec);

			std::cout << "Current local time is: " << buffer << std::endl;
		}
	}

	return 0;
}
