/*! \file counter.c
 * utility routines for keeping some statistics. */
/*
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 *
 * 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 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.
 *
 */

#include <string.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/counter.h>

static LLIST_HEAD(counters);

/*! Global talloc context for all osmo_counter allocations. */
void *tall_ctr_ctx;

/*! Allocate a new counter with given name. Allocates from tall_ctr_ctx
 *  \param[in] name Human-readable string name for the counter
 *  \returns Allocated counter on success; NULL on error */
struct osmo_counter *osmo_counter_alloc(const char *name)
{
	struct osmo_counter *ctr = talloc_zero(tall_ctr_ctx, struct osmo_counter);

	if (!ctr)
		return NULL;

	ctr->name = name;
	llist_add_tail(&ctr->list, &counters);

	return ctr;
}

/*! Release/Destroy a given counter
 *  \param[in] ctr Counter to be destroyed */
void osmo_counter_free(struct osmo_counter *ctr)
{
	llist_del(&ctr->list);
	talloc_free(ctr);
}

/*! Iterate over all counters; call \a handle_cunter call-back for each.
 *  \param[in] handle_counter Call-back to be called for each counter; aborts if rc < 0
 *  \param[in] data Opaque data passed through to \a handle_counter function
 *  \returns 0 if all \a handle_counter calls successfull; negative on error */
int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *),
			   void *data)
{
	struct osmo_counter *ctr;
	int rc = 0;

	llist_for_each_entry(ctr, &counters, list) {
		rc = handle_counter(ctr, data);
		if (rc < 0)
			return rc;
	}

	return rc;
}

/*! Find a counter by its name.
 *  \param[in] name Name used to look-up/search counter
 *  \returns Counter on success; NULL if not found */
struct osmo_counter *osmo_counter_get_by_name(const char *name)
{
	struct osmo_counter *ctr;

	llist_for_each_entry(ctr, &counters, list) {
		if (!strcmp(ctr->name, name))
			return ctr;
	}
	return NULL;
}

/*! Compute difference between current and previous counter value.
 *  \param[in] ctr Counter of which the difference is to be computed
 *  \returns Delta value between current counter and previous counter. Please
 *	     note that the actual counter values are unsigned long, while the
 *	     difference is computed as signed integer! */
int osmo_counter_difference(struct osmo_counter *ctr)
{
	int delta = ctr->value - ctr->previous;
	ctr->previous = ctr->value;

	return delta;
}
