/*
 *  Realtime timer with GLib integration
 *
 *  Copyright (C) 2014  Nest Labs. 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
 *
 */

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

#include "timer.h"

/*
 * A GLib custom event source using a POSIX fd timer that becomes
 * 'ready' on timer expiration. Timer 'advances' across a suspend but
 * has no ability to bring system out of suspend. Timer will fire upon
 * resume if expired.
 */

typedef struct _GRTimeoutSource GRTimeoutSource;

struct _GRTimeoutSource
{
	GSource	source;
	GPollFD	pfd;
	guint interval;
};

static gboolean g_rttimeout_prepare (GSource *source, gint *timeout);
static gboolean g_rttimeout_check (GSource *source);
static gboolean g_rttimeout_dispatch (GSource *source, GSourceFunc callback,
				     gpointer user_data);

GSourceFuncs g_rttimeout_funcs =
{
	g_rttimeout_prepare,
	g_rttimeout_check,
	g_rttimeout_dispatch,
	NULL
};

void g_rttimeout_info(const char *format, ...)
{
	va_list ap;

	va_start(ap, format);
	vsyslog(LOG_INFO, format, ap);
	va_end(ap);
}

static gboolean g_rttimeout_prepare (GSource *source, gint *timeout)
{
	*timeout = -1;

	return FALSE;
}

static gboolean g_rttimeout_check (GSource *source)
{
	GRTimeoutSource *timeout_source = (GRTimeoutSource *)source;

	return timeout_source->pfd.revents & G_IO_IN;
}

static gboolean
g_rttimeout_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
{
	GRTimeoutSource *timeout_source = (GRTimeoutSource *)source;
	gboolean again;

	g_rttimeout_info("DHCP: %s: fd=%d, source=%p, user_data=%p",
			__func__, timeout_source->pfd.fd, source, user_data);
	if (!callback) {
		g_warning ("GR timeout source dispatched without callback\n"
			   "You must call g_source_set_callback().");
		if (!g_source_is_destroyed (source)) {
			g_source_remove_poll (source, &timeout_source->pfd);
			close(timeout_source->pfd.fd);
		}
		return FALSE;
	}

	again = callback (user_data);

	if (again) {
		struct itimerspec timer_value;
		int result;

		/* arm the timer as a single-shot */
		timer_value.it_value.tv_sec = timeout_source->interval;
		timer_value.it_value.tv_nsec = 0;
		timer_value.it_interval.tv_sec = 0;
		timer_value.it_interval.tv_nsec = 0;

		result = timerfd_settime (timeout_source->pfd.fd, 0,
					  &timer_value, NULL);
		if (result == -1)
			g_error ("%s: error calling timer_settime", G_STRLOC);
	} else {
		if (!g_source_is_destroyed (source)) {
			g_source_remove_poll (source, &timeout_source->pfd);
			close(timeout_source->pfd.fd);
		}
	}

	return again;
}

/**
 * g_rttimeout_add_seconds_full:
 */
guint g_rttimeout_add_seconds_full (gint type, gint priority, guint32 interval,
				   GSourceFunc function, gpointer data,
				   GDestroyNotify notify)
{
  return g_rttimeout_add_full(type, priority, interval * 1000,
				   function, data, notify);
}

/**
 * g_rttimeout_add_full:
 */
guint g_rttimeout_add_full (gint type, gint priority, guint32 interval,
			   GSourceFunc function, gpointer data,
			   GDestroyNotify notify)
{
	GSource *source;
	int fd;
	guint id;

	g_return_val_if_fail (function != NULL, 0);

	source = g_source_new (&g_rttimeout_funcs, sizeof (GRTimeoutSource));
	if (priority != G_PRIORITY_DEFAULT)
		g_source_set_priority (source, priority);
	g_source_set_callback (source, function, data, notify);
	id = g_source_attach (source, NULL);
	g_source_unref (source);

	fd = timerfd_create(type, 0);
	if (fd != -1) {
		GRTimeoutSource *timeout_source = (GRTimeoutSource *)source;
		struct itimerspec timer_value;
		struct timespec now;
		int result;

		g_rttimeout_info("DHCP: %s: id=%d fd=%d, source=%p, seconds=%d",
				__func__, id, fd, source, interval/1000);
		memset(&timer_value, 0, sizeof(struct itimerspec));

		clock_gettime(type, &now);
		timer_value.it_value.tv_sec = now.tv_sec + interval / 1000;
		timer_value.it_value.tv_nsec =
			now.tv_nsec + ((interval % 1000) * 1000000);

		/* arm the timer as a single-shot */
		result = timerfd_settime (fd, TFD_TIMER_ABSTIME, &timer_value,
					  NULL);
		if (result != -1) {
			timeout_source->interval = interval;
			timeout_source->pfd.fd = fd;
			timeout_source->pfd.events = G_IO_IN;

			g_source_add_poll(source, &timeout_source->pfd);
		} else {
			g_rttimeout_info("DHCP: %s: error timerfd_settime, err=%d\n", 
				__func__, errno);
			g_error ("%s: error calling timerfd_settime", G_STRLOC);
		}
	} else {
		g_error ("%s: error calling timerfd_create", G_STRLOC);
	}

	return id;
}

gboolean g_rttimeout_source_remove(guint id)
{
	GSource *source;

	g_return_val_if_fail (id > 0, FALSE);
	source = g_main_context_find_source_by_id (NULL, id);
	if (source) {
		GRTimeoutSource *timeout_source = (GRTimeoutSource *)source;

		if (!g_source_is_destroyed (source)) {
			g_rttimeout_info("DHCP: %s: id=%d fd=%d source=%p",
					__func__, id, timeout_source->pfd.fd,
					source);
			g_source_remove_poll (source, &timeout_source->pfd);
			close(timeout_source->pfd.fd);
			g_source_destroy (source);
		}
	} else {
		g_rttimeout_info("DHCP: %s: id=%d not found", __func__, id);
	}

	return source != NULL;
}
