#include "util.h"

#include <math.h>				 /* round */
#include <stdarg.h>				 /* va_list */
#include <stdint.h>				 /* uint8_t */
#include <stdio.h>				 /* printf */
#include <stdlib.h>				 /* exit */

void
error (const char* fmt, ...)
{
	va_list argp;
	va_start (argp, fmt);
	vfprintf (stderr, fmt, argp);
	va_end (argp);
	fputc ('\n', stderr);
	fflush (stderr);
	exit (EXIT_FAILURE);
}


int
util_IsProbablyAscii (const void* buf, const size_t len)
{
	const uint8_t* bufPtr;
	const uint8_t* bufPtrEnd;
	size_t nAsciiCount;
	nAsciiCount = 0;
	bufPtr = (const uint8_t*) buf;
	bufPtrEnd = bufPtr + len;
	while (bufPtr < bufPtrEnd && (NULL != bufPtr) && (*bufPtr != '\0'))
	{
		nAsciiCount += (*bufPtr >= ' ') && (*bufPtr <= '~');
		bufPtr++;
	}
	return (int) round ((double) nAsciiCount / (double) len);
}


void
util_HexDump (const void* buf, const size_t len)
{
	const uint8_t* bufPtr;
	const uint8_t* bufPtrEnd;
	const size_t width = 16;
	size_t nout;
	nout = 0;
	bufPtr = (const uint8_t*) buf;
	bufPtrEnd = bufPtr + len;
	while (bufPtr < bufPtrEnd && (NULL != bufPtr))
	{
		if (nout == width)
		{
			printf ("\n");
			nout = 0;
		}
		printf ("%02x ", *bufPtr);
		bufPtr++;
		nout++;
	}
	puts ("");
}


void
util_UDP_DumpPacket (UDPpacket* packet)
{
	const uint8_t* buf;

	SDL_assert (packet != NULL);
	// SDL_assert (packet->len > 0);

	SDL_Log ("address: %s:%d", SDLNet_ResolveIP (&packet->address), SDLNet_Read16 (&packet->address.port));
	SDL_Log ("channel: %d", packet->channel);
	SDL_Log ("len    : %d", packet->len);
	SDL_Log ("maxlen : %d", packet->maxlen);
	SDL_Log ("status : %d", packet->status);

	if (packet->len > 0)
	{
		buf = (const uint8_t*)packet->data;
		// if (util_IsProbablyAscii (buf, packet->len))
		// 	SDL_Log ("data:\n%s\n", buf);
		// else
			util_HexDump (buf, packet->len);
	}
	else
	{
		SDL_Log ("No packet data!");
	}

	//DEBUG_LOG ("%d bytes from %s:%d:\n%s", packet->len, hoststring, ntohs (packet->address.port), str.c_str ());
}