/*
 *
 *  AT chat library with GLib integration
 *
 *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <glib.h>

#include "gatutil.h"

void g_at_util_debug_chat(gboolean in, const char *str, gsize len,
				GAtDebugFunc debugf, gpointer user_data)
{
	char type = in ? '<' : '>';
	gsize escaped = 2; /* Enough for '<', ' ' */
	char *escaped_str;
	const char *esc = "<ESC>";
	gsize esc_size = strlen(esc);
	const char *ctrlz = "<CtrlZ>";
	gsize ctrlz_size = strlen(ctrlz);
	gsize i;

	if (debugf == NULL || !len)
		return;

	for (i = 0; i < len; i++) {
		char c = str[i];

		if (g_ascii_isprint(c))
			escaped += 1;
		else if (c == '\r' || c == '\t' || c == '\n')
			escaped += 2;
		else if (c == 26)
			escaped += ctrlz_size;
		else if (c == 25)
			escaped += esc_size;
		else
			escaped += 4;
	}

	escaped_str = g_try_malloc(escaped + 1);
	if (escaped_str == NULL)
		return;

	escaped_str[0] = type;
	escaped_str[1] = ' ';
	memset(escaped_str + 2, '\0', escaped - 1);

	for (escaped = 2, i = 0; i < len; i++) {
		unsigned char c = str[i];

		switch (c) {
		case '\r':
			escaped_str[escaped++] = '\\';
			escaped_str[escaped++] = 'r';
			break;
		case '\t':
			escaped_str[escaped++] = '\\';
			escaped_str[escaped++] = 't';
			break;
		case '\n':
			escaped_str[escaped++] = '\\';
			escaped_str[escaped++] = 'n';
			break;
		case 26:
			memcpy(escaped_str + escaped, ctrlz, ctrlz_size);
			escaped += ctrlz_size;
			break;
		case 25:
			memcpy(escaped_str + escaped, esc, esc_size);
			escaped += esc_size;
			break;
		default:
			if (g_ascii_isprint(c))
				escaped_str[escaped++] = c;
			else {
				escaped_str[escaped++] = '\\';
				escaped_str[escaped++] = '0' + ((c >> 6) & 07);
				escaped_str[escaped++] = '0' + ((c >> 3) & 07);
				escaped_str[escaped++] = '0' + (c & 07);
			}
		}
	}

	debugf(escaped_str, user_data);
	g_free(escaped_str);
}

void g_at_util_debug_dump(gboolean in, const unsigned char *buf, gsize len,
				GAtDebugFunc debugf, gpointer user_data)
{
	char type = in ? '<' : '>';
	GString *str;
	gsize i;

	if (debugf == NULL || !len)
		return;

	str = g_string_sized_new(1 + (len * 2));
	if (str == NULL)
		return;

	g_string_append_c(str, type);

	for (i = 0; i < len; i++)
		g_string_append_printf(str, " %02x", buf[i]);

	debugf(str->str, user_data);
	g_string_free(str, TRUE);
}

void g_at_util_debug_hexdump(gboolean in, const unsigned char *buf, gsize len,
				GAtDebugFunc debugf, gpointer user_data)
{
	static const char hexdigits[] = "0123456789abcdef";
	char str[68];
	gsize i;

	if (debugf == NULL || !len)
		return;

	str[0] = in ? '<' : '>';

	for (i = 0; i < len; i++) {
		str[((i % 16) * 3) + 1] = ' ';
		str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4];
		str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf];
		str[(i % 16) + 51] = g_ascii_isprint(buf[i]) ? buf[i] : '.';

		if ((i + 1) % 16 == 0) {
			str[49] = ' ';
			str[50] = ' ';
			str[67] = '\0';
			debugf(str, user_data);
			str[0] = ' ';
		}
	}

	if (i % 16 > 0) {
		gsize j;
		for (j = (i % 16); j < 16; j++) {
			str[(j * 3) + 1] = ' ';
			str[(j * 3) + 2] = ' ';
			str[(j * 3) + 3] = ' ';
			str[j + 51] = ' ';
		}
		str[49] = ' ';
		str[50] = ' ';
		str[67] = '\0';
		debugf(str, user_data);
	}
}

gboolean g_at_util_setup_io(GIOChannel *io, GIOFlags flags)
{
	GIOFlags io_flags;

	if (g_io_channel_set_encoding(io, NULL, NULL) != G_IO_STATUS_NORMAL)
		return FALSE;

	g_io_channel_set_buffered(io, FALSE);

	if (flags & G_IO_FLAG_SET_MASK) {
		io_flags = g_io_channel_get_flags(io);

		io_flags |= (flags & G_IO_FLAG_SET_MASK);

		if (g_io_channel_set_flags(io, io_flags, NULL) !=
							G_IO_STATUS_NORMAL)
			return FALSE;
	}

	g_io_channel_set_close_on_unref(io, TRUE);

	return TRUE;
}
