/*
 *
 *  Web service library with GLib integration
 *
 *  Copyright (C) 2009-2012  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 <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <gnutls/gnutls.h>

#include "giognutls.h"

//#define DBG(fmt, arg...)  printf("%s: " fmt "\n" , __func__ , ## arg)
#define DBG(fmt, arg...)

typedef struct _GIOGnuTLSChannel GIOGnuTLSChannel;
typedef struct _GIOGnuTLSWatch GIOGnuTLSWatch;

struct _GIOGnuTLSChannel {
	GIOChannel channel;
	gint fd;
	gnutls_certificate_credentials_t cred;
	gnutls_session_t session;
	gboolean established;
	gboolean again;
};

struct _GIOGnuTLSWatch {
	GSource source;
	GPollFD pollfd;
	GIOChannel *channel;
	GIOCondition condition;
};

static volatile int global_init_done = 0;

static inline void g_io_gnutls_global_init(void)
{
	if (__sync_bool_compare_and_swap(&global_init_done, 0, 1) == TRUE)
		gnutls_global_init();
}

static GIOStatus check_handshake(GIOChannel *channel, GError **err)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	int result;

	DBG("channel %p", channel);

	if (gnutls_channel->established == TRUE)
		return G_IO_STATUS_NORMAL;

again:
	result = gnutls_handshake(gnutls_channel->session);

	if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
		GIOFlags flags = g_io_channel_get_flags(channel);

		if (gnutls_channel->again == TRUE)
			return G_IO_STATUS_AGAIN;

		if (flags & G_IO_FLAG_NONBLOCK)
			return G_IO_STATUS_AGAIN;

		goto again;
	}

	if (result < 0) {
		g_set_error(err, G_IO_CHANNEL_ERROR,
				G_IO_CHANNEL_ERROR_FAILED, "Handshake failed");
		return G_IO_STATUS_ERROR;
	}

	gnutls_channel->established = TRUE;

	DBG("handshake done");

	return G_IO_STATUS_NORMAL;
}

static GIOStatus g_io_gnutls_read(GIOChannel *channel, gchar *buf,
				gsize count, gsize *bytes_read, GError **err)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	GIOStatus status;
	ssize_t result;

	DBG("channel %p count %zu", channel, count);

	*bytes_read = 0;

again:
	status = check_handshake(channel, err);
	if (status != G_IO_STATUS_NORMAL)
		return status;

	result = gnutls_record_recv(gnutls_channel->session, buf, count);

	DBG("result %zd", result);

	if (result == GNUTLS_E_REHANDSHAKE) {
		gnutls_channel->established = FALSE;
		goto again;
	}

	if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
		GIOFlags flags = g_io_channel_get_flags(channel);

		if (gnutls_channel->again == TRUE)
			return G_IO_STATUS_AGAIN;

		if (flags & G_IO_FLAG_NONBLOCK)
			return G_IO_STATUS_AGAIN;

		goto again;
	}

	if (result == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
		return G_IO_STATUS_EOF;

	if (result < 0) {
		g_set_error(err, G_IO_CHANNEL_ERROR,
				G_IO_CHANNEL_ERROR_FAILED, "Stream corrupted");
		return G_IO_STATUS_ERROR;
	}

	*bytes_read = result;

	return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
}

static GIOStatus g_io_gnutls_write(GIOChannel *channel, const gchar *buf,
				gsize count, gsize *bytes_written, GError **err)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	GIOStatus status;
	ssize_t result;

	DBG("channel %p count %zu", channel, count);

	*bytes_written = 0;

again:
	status = check_handshake(channel, err);
	if (status != G_IO_STATUS_NORMAL)
		return status;

	result = gnutls_record_send(gnutls_channel->session, buf, count);

	DBG("result %zd", result);

	if (result == GNUTLS_E_REHANDSHAKE) {
		gnutls_channel->established = FALSE;
		goto again;
	}

	if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
		GIOFlags flags = g_io_channel_get_flags(channel);

		if (gnutls_channel->again == TRUE)
			return G_IO_STATUS_AGAIN;

		if (flags & G_IO_FLAG_NONBLOCK)
			return G_IO_STATUS_AGAIN;

		goto again;
	}

	if (result < 0) {
		g_set_error(err, G_IO_CHANNEL_ERROR,
				G_IO_CHANNEL_ERROR_FAILED, "Stream corrupted");
		return G_IO_STATUS_ERROR;
        }

	*bytes_written = result;

	return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
}

static GIOStatus g_io_gnutls_seek(GIOChannel *channel, gint64 offset,
						GSeekType type, GError **err)
{
	DBG("channel %p", channel);

	g_set_error_literal(err, G_IO_CHANNEL_ERROR,
				G_IO_CHANNEL_ERROR_FAILED, "Not supported");
	return G_IO_STATUS_ERROR;
}

static GIOStatus g_io_gnutls_close(GIOChannel *channel, GError **err)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;

	DBG("channel %p", channel);

	if (gnutls_channel->established == TRUE)
		gnutls_bye(gnutls_channel->session, GNUTLS_SHUT_RDWR);

	if (close(gnutls_channel->fd) < 0) {
		g_set_error_literal(err, G_IO_CHANNEL_ERROR,
				G_IO_CHANNEL_ERROR_FAILED, "Closing failed");
		return G_IO_STATUS_ERROR;
	}

	return G_IO_STATUS_NORMAL;
}

static void g_io_gnutls_free(GIOChannel *channel)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;

	DBG("channel %p", channel);

	gnutls_deinit(gnutls_channel->session);

	gnutls_certificate_free_credentials(gnutls_channel->cred);

	g_free(gnutls_channel);
}

static GIOStatus g_io_gnutls_set_flags(GIOChannel *channel,
						GIOFlags flags, GError **err)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	glong fcntl_flags = 0;

	DBG("channel %p flags %u", channel, flags);

	if (flags & G_IO_FLAG_NONBLOCK)
		fcntl_flags |= O_NONBLOCK;

	if (fcntl(gnutls_channel->fd, F_SETFL, fcntl_flags) < 0) {
		g_set_error_literal(err, G_IO_CHANNEL_ERROR,
			G_IO_CHANNEL_ERROR_FAILED, "Setting flags failed");
		return G_IO_STATUS_ERROR;
	}

	return G_IO_STATUS_NORMAL;
}

static GIOFlags g_io_gnutls_get_flags(GIOChannel *channel)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	GIOFlags flags = 0;
	glong fcntl_flags;

	DBG("channel %p", channel);

	fcntl_flags = fcntl(gnutls_channel->fd, F_GETFL);
	if (fcntl_flags < 0)
		return 0;

	if (fcntl_flags & O_NONBLOCK)
		flags |= G_IO_FLAG_NONBLOCK;

	return flags;
}

static gboolean g_io_gnutls_prepare(GSource *source, gint *timeout)
{
	DBG("source %p", source);

	*timeout = -1;

	return FALSE;
}

static gboolean g_io_gnutls_check(GSource *source)
{
	GIOGnuTLSWatch *watch = (GIOGnuTLSWatch *) source;
	GIOCondition condition = watch->pollfd.revents;

	DBG("source %p condition %u", source, condition);

	if (condition & watch->condition)
		return TRUE;

	return FALSE;
}

static gboolean g_io_gnutls_dispatch(GSource *source, GSourceFunc callback,
							gpointer user_data)
{
	GIOGnuTLSWatch *watch = (GIOGnuTLSWatch *) source;
	GIOFunc func = (GIOFunc) callback;
	GIOCondition condition = watch->pollfd.revents;

	DBG("source %p condition %u", source, condition);

	if (func == NULL)
		return FALSE;

	return func(watch->channel, condition & watch->condition, user_data);
}

static void g_io_gnutls_finalize(GSource *source)
{
	GIOGnuTLSWatch *watch = (GIOGnuTLSWatch *) source;

	DBG("source %p", source);

	g_io_channel_unref(watch->channel);
}

static GSourceFuncs gnutls_watch_funcs = {
	g_io_gnutls_prepare,
	g_io_gnutls_check,
	g_io_gnutls_dispatch,
	g_io_gnutls_finalize,
};

static GSource *g_io_gnutls_create_watch(GIOChannel *channel,
						GIOCondition condition)
{
	GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel;
	GIOGnuTLSWatch *watch;
	GSource *source;

	DBG("channel %p condition %u", channel, condition);

	source = g_source_new(&gnutls_watch_funcs, sizeof(GIOGnuTLSWatch));

	watch = (GIOGnuTLSWatch *) source;

	watch->channel = channel;
	g_io_channel_ref(channel);

	watch->condition = condition;

	watch->pollfd.fd = gnutls_channel->fd;
	watch->pollfd.events = condition;

	g_source_add_poll(source, &watch->pollfd);

	return source;
}

static GIOFuncs gnutls_channel_funcs = {
	g_io_gnutls_read,
	g_io_gnutls_write,
	g_io_gnutls_seek,
	g_io_gnutls_close,
	g_io_gnutls_create_watch,
	g_io_gnutls_free,
	g_io_gnutls_set_flags,
	g_io_gnutls_get_flags,
};

static ssize_t g_io_gnutls_push_func(gnutls_transport_ptr_t transport_data,
						const void *buf, size_t count)
{
	GIOGnuTLSChannel *gnutls_channel = transport_data;
	ssize_t result;

	DBG("count %zu", count);

	result = write(gnutls_channel->fd, buf, count);

	if (result < 0 && errno == EAGAIN)
		gnutls_channel->again = TRUE;
	else
		gnutls_channel->again = FALSE;

	DBG("result %zd", result);

	return result;
}

static ssize_t g_io_gnutls_pull_func(gnutls_transport_ptr_t transport_data,
						void *buf, size_t count)
{
	GIOGnuTLSChannel *gnutls_channel = transport_data;
	ssize_t result;

	DBG("count %zu", count);

	result = read(gnutls_channel->fd, buf, count);

	if (result < 0 && errno == EAGAIN)
		gnutls_channel->again = TRUE;
	else
		gnutls_channel->again = FALSE;

	DBG("result %zd", result);

	return result;
}

gboolean g_io_channel_supports_tls(void)
{
	return TRUE;
}

GIOChannel *g_io_channel_gnutls_new(int fd)
{
	GIOGnuTLSChannel *gnutls_channel;
	GIOChannel *channel;
	int err;

	DBG("");

	gnutls_channel = g_new(GIOGnuTLSChannel, 1);

	channel = (GIOChannel *) gnutls_channel;

	g_io_channel_init(channel);
	channel->funcs = &gnutls_channel_funcs;

	gnutls_channel->fd = fd;

	channel->is_seekable = FALSE;
	channel->is_readable = TRUE;
	channel->is_writeable = TRUE;

	channel->do_encode = FALSE;

	g_io_gnutls_global_init();

        err = gnutls_init(&gnutls_channel->session, GNUTLS_CLIENT);
	if (err < 0) {
		g_free(gnutls_channel);
		return NULL;
	}

	gnutls_transport_set_ptr(gnutls_channel->session, gnutls_channel);
        gnutls_transport_set_push_function(gnutls_channel->session,
						g_io_gnutls_push_func);
        gnutls_transport_set_pull_function(gnutls_channel->session,
						g_io_gnutls_pull_func);
#if GNUTLS_VERSION_NUMBER < 0x020c00
	gnutls_transport_set_lowat(gnutls_channel->session, 0);

	gnutls_priority_set_direct(gnutls_channel->session,
						"NORMAL:%COMPAT", NULL);
#else
	gnutls_priority_set_direct(gnutls_channel->session,
		"NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL);
#endif

	gnutls_certificate_allocate_credentials(&gnutls_channel->cred);
	gnutls_credentials_set(gnutls_channel->session,
				GNUTLS_CRD_CERTIFICATE, gnutls_channel->cred);

	DBG("channel %p", channel);

	return channel;
}
