/*
 * (C) 2008,2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2011 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved
 *
 * Authors: Holger Hans Peter Freyther <zecke@selfish.org>
 *	    Harald Welte <laforge@gnumonks.org>
 *	    Pablo Neira Ayuso <pablo@gnumonks.org>
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */


/*! \addtogroup timer
 *  @{
 *  Osmocom timer abstraction; modelled after linux kernel timers
 *
 * \file timer.c */

#include <assert.h>
#include <string.h>
#include <limits.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/timer_compat.h>
#include <osmocom/core/linuxlist.h>

/* These store the amount of time that we wait until next timer expires. */
static struct timeval nearest;
static struct timeval *nearest_p;

static struct rb_root timer_root = RB_ROOT;

static void __add_timer(struct osmo_timer_list *timer)
{
	struct rb_node **new = &(timer_root.rb_node);
	struct rb_node *parent = NULL;

	while (*new) {
		struct osmo_timer_list *this;

		this = container_of(*new, struct osmo_timer_list, node);

		parent = *new;
		if (timercmp(&timer->timeout, &this->timeout, <))
			new = &((*new)->rb_left);
		else
			new = &((*new)->rb_right);
	}

	rb_link_node(&timer->node, parent, new);
	rb_insert_color(&timer->node, &timer_root);
}

/*! set up timer callback and data
 *  \param[in] timer the timer that should be added
 *  \param[in] callback function to be called when timer expires
 *  \param[in] pointer to data that passed to the callback function
 */
void osmo_timer_setup(struct osmo_timer_list *timer, void (*cb)(void *data),
		      void *data)
{
	timer->cb	= cb;
	timer->data	= data;
}

/*! add a new timer to the timer management
 *  \param[in] timer the timer that should be added
 */
void osmo_timer_add(struct osmo_timer_list *timer)
{
	osmo_timer_del(timer);
	timer->active = 1;
	INIT_LLIST_HEAD(&timer->list);
	__add_timer(timer);
}

/*! schedule a timer at a given future relative time
 *  \param[in] timer the to-be-added timer
 *  \param[in] seconds number of seconds from now
 *  \param[in] microseconds number of microseconds from now
 *
 * This function can be used to (re-)schedule a given timer at a
 * specified number of seconds+microseconds in the future.  It will
 * internally add it to the timer management data structures, thus
 * osmo_timer_add() is automatically called.
 */
void
osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds)
{
	struct timeval current_time;

	osmo_gettimeofday(&current_time, NULL);
	timer->timeout.tv_sec = seconds;
	timer->timeout.tv_usec = microseconds;
	timeradd(&timer->timeout, &current_time, &timer->timeout);
	osmo_timer_add(timer);
}

/*! delete a timer from timer management
 *  \param[in] timer the to-be-deleted timer
 *
 * This function can be used to delete a previously added/scheduled
 * timer from the timer management code.
 */
void osmo_timer_del(struct osmo_timer_list *timer)
{
	if (timer->active) {
		timer->active = 0;
		rb_erase(&timer->node, &timer_root);
		/* make sure this is not already scheduled for removal. */
		if (!llist_empty(&timer->list))
			llist_del_init(&timer->list);
	}
}

/*! check if given timer is still pending
 *  \param[in] timer the to-be-checked timer
 *  \return 1 if pending, 0 otherwise
 *
 * This function can be used to determine whether a given timer
 * has alredy expired (returns 0) or is still pending (returns 1)
 */
int osmo_timer_pending(struct osmo_timer_list *timer)
{
	return timer->active;
}

/*! compute the remaining time of a timer
 *  \param[in] timer the to-be-checked timer
 *  \param[in] now the current time (NULL if not known)
 *  \param[out] remaining remaining time until timer fires
 *  \return 0 if timer has not expired yet, -1 if it has
 *
 *  This function can be used to determine the amount of time
 *  remaining until the expiration of the timer.
 */
int osmo_timer_remaining(const struct osmo_timer_list *timer,
			 const struct timeval *now,
			 struct timeval *remaining)
{
	struct timeval current_time;

	if (!now)
		osmo_gettimeofday(&current_time, NULL);
	else
		current_time = *now;

	timersub(&timer->timeout, &current_time, remaining);

	if (remaining->tv_sec < 0)
		return -1;

	return 0;
}

/*! Determine time between now and the nearest timer
 *  \returns pointer to timeval of nearest timer, NULL if there is none
 *
 * if we have a nearest time return the delta between the current
 * time and the time of the nearest timer.
 * If the nearest timer timed out return NULL and then we will
 * dispatch everything after the select
 */
struct timeval *osmo_timers_nearest(void)
{
	/* nearest_p is exactly what we need already: NULL if nothing is
	 * waiting, {0,0} if we must dispatch immediately, and the correct
	 * delay if we need to wait */
	return nearest_p;
}

static void update_nearest(struct timeval *cand, struct timeval *current)
{
	if (cand->tv_sec != LONG_MAX) {
		if (timercmp(cand, current, >))
			timersub(cand, current, &nearest);
		else {
			/* loop again inmediately */
			timerclear(&nearest);
		}
		nearest_p = &nearest;
	} else {
		nearest_p = NULL;
	}
}

/*! Find the nearest time and update nearest_p */
void osmo_timers_prepare(void)
{
	struct rb_node *node;
	struct timeval current;

	osmo_gettimeofday(&current, NULL);

	node = rb_first(&timer_root);
	if (node) {
		struct osmo_timer_list *this;
		this = container_of(node, struct osmo_timer_list, node);
		update_nearest(&this->timeout, &current);
	} else {
		nearest_p = NULL;
	}
}

/*! fire all timers... and remove them */
int osmo_timers_update(void)
{
	struct timeval current_time;
	struct rb_node *node;
	struct llist_head timer_eviction_list;
	struct osmo_timer_list *this;
	int work = 0;

	osmo_gettimeofday(&current_time, NULL);

	INIT_LLIST_HEAD(&timer_eviction_list);
	for (node = rb_first(&timer_root); node; node = rb_next(node)) {
		this = container_of(node, struct osmo_timer_list, node);

		if (timercmp(&this->timeout, &current_time, >))
			break;

		llist_add(&this->list, &timer_eviction_list);
	}

	/*
	 * The callbacks might mess with our list and in this case
	 * even llist_for_each_entry_safe is not safe to use. To allow
	 * osmo_timer_del to be called from within the callback we need
	 * to restart the iteration for each element scheduled for removal.
	 *
	 * The problematic scenario is the following: Given two timers A
	 * and B that have expired at the same time. Thus, they are both
	 * in the eviction list in this order: A, then B. If we remove
	 * timer B from the A's callback, we continue with B in the next
	 * iteration step, leading to an access-after-release.
	 */
restart:
	llist_for_each_entry(this, &timer_eviction_list, list) {
		osmo_timer_del(this);
		if (this->cb)
			this->cb(this->data);
		work = 1;
		goto restart;
	}

	return work;
}

/*! Check how many timers we have in the system
 *  \returns number of \ref osmo_timer_list registered */
int osmo_timers_check(void)
{
	struct rb_node *node;
	int i = 0;

	for (node = rb_first(&timer_root); node; node = rb_next(node)) {
		i++;
	}
	return i;
}

/*! @} */
