/*
 *  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;
        gpointer tag;
};

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;
        gpointer tag;

	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;
		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));

		timer_value.it_value.tv_sec = interval / 1000;
		timer_value.it_value.tv_nsec = 0;

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

                        tag = g_source_add_unix_fd(source, fd, G_IO_IN);

                        if (tag != NULL) {
                            timeout_source->tag = tag;
                        } else {
                            g_rttimeout_info("DHCP: %s: cannot attach fd to source\n", __func__);
                            g_error ("%s: error calling g_source_add_unix_fd", G_STRLOC);
                        }
		} 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_unix_fd(source, timeout_source->tag);
			close(timeout_source->pfd.fd);
			g_source_destroy (source);
		}
	} else {
		g_rttimeout_info("DHCP: %s: id=%d not found", __func__, id);
	}

	return source != NULL;
}
