/*
 * (C) 2015 by sysmocom - s.f.m.c. GmbH
 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
 * All Rights Reserved
 *
 * 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 stats
 *  @{
 *  \file stats_statsd.c */

#include "config.h"
#if !defined(EMBEDDED)

#include <osmocom/core/stats.h>

#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/stats.h>

static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
	const struct rate_ctr_group *ctrg,
	const struct rate_ctr_desc *desc,
	int64_t value, int64_t delta);
static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
	const struct osmo_stat_item_group *statg,
	const struct osmo_stat_item_desc *desc, int64_t value);

/*! Create a stats_reporter reporting to statsd.  This creates a stats_reporter
 *  instance which reports the related statistics data to statsd.
 *  \param[in] name Name of the to-be-created stats_reporter
 *  \returns stats_reporter on success; NULL on error */
struct osmo_stats_reporter *osmo_stats_reporter_create_statsd(const char *name)
{
	struct osmo_stats_reporter *srep;
	srep = osmo_stats_reporter_alloc(OSMO_STATS_REPORTER_STATSD, name);

	srep->have_net_config = 1;

	srep->open = osmo_stats_reporter_udp_open;
	srep->close = osmo_stats_reporter_udp_close;
	srep->send_counter = osmo_stats_reporter_statsd_send_counter;
	srep->send_item = osmo_stats_reporter_statsd_send_item;

	return srep;
}

/*! Replace all illegal ':' in the stats name, but not when used as value seperator.
 *  ':' is used as seperator between the name and the value in the statsd protocol.
 *  \param[inout] buf is a null terminated string containing name, value, unit. */
static void osmo_stats_reporter_sanitize_name(char *buf)
{
	/* e.g. msc.loc_update_type:normal:1|c -> msc.loc_update_type.normal:1|c
	 * last is the seperator between name and value */
	char *last = strrchr(buf, ':');
	char *tmp = strchr(buf, ':');

	if (!last)
		return;

	while (tmp < last) {
		*tmp = '.';
		tmp = strchr(buf, ':');
	}
}

static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
	const char *name1, unsigned int index1, const char *name2, int64_t value,
	const char *unit)
{
	char *buf;
	int buf_size;
	int nchars, rc = 0;
	char *fmt = NULL;
	char *prefix = srep->name_prefix;
	int old_len = msgb_length(srep->buffer);

	if (prefix) {
		if (name1)
			fmt = "%1$s.%2$s.%6$u.%3$s:%4$" PRId64 "|%5$s";
		else
			fmt = "%1$s.%2$0.0s%3$s:%4$" PRId64 "|%5$s";
	} else {
		prefix = "";
		if (name1)
			fmt = "%1$s%2$s.%6$u.%3$s:%4$" PRId64 "|%5$s";
		else
			fmt = "%1$s%2$0.0s%3$s:%4$" PRId64 "|%5$s";
	}

	if (srep->agg_enabled) {
		if (msgb_length(srep->buffer) > 0 &&
			msgb_tailroom(srep->buffer) > 0)
		{
			msgb_put_u8(srep->buffer, '\n');
		}
	}

	buf = (char *)msgb_put(srep->buffer, 0);
	buf_size = msgb_tailroom(srep->buffer);

	nchars = snprintf(buf, buf_size, fmt,
		prefix, name1, name2,
		value, unit, index1);

	if (nchars >= buf_size) {
		/* Truncated */
		/* Restore original buffer (without trailing LF) */
		msgb_trim(srep->buffer, old_len);
		/* Send it */
		rc = osmo_stats_reporter_send_buffer(srep);

		/* Try again */
		buf = (char *)msgb_put(srep->buffer, 0);
		buf_size = msgb_tailroom(srep->buffer);

		nchars = snprintf(buf, buf_size, fmt,
			prefix, name1, name2,
			value, unit, index1);

		if (nchars >= buf_size)
			return -EMSGSIZE;
	}

	if (nchars > 0) {
		osmo_stats_reporter_sanitize_name(buf);
		msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);
	}

	if (!srep->agg_enabled)
		rc = osmo_stats_reporter_send_buffer(srep);

	return rc;
}

static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
	const struct rate_ctr_group *ctrg,
	const struct rate_ctr_desc *desc,
	int64_t value, int64_t delta)
{
	if (ctrg)
		return osmo_stats_reporter_statsd_send(srep,
			ctrg->desc->group_name_prefix,
			ctrg->idx,
			desc->name, delta, "c");
	else
		return osmo_stats_reporter_statsd_send(srep,
			NULL, 0,
			desc->name, delta, "c");
}

static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
	const struct osmo_stat_item_group *statg,
	const struct osmo_stat_item_desc *desc, int64_t value)
{
	if (value < 0) {
		return osmo_stats_reporter_statsd_send(srep,
				statg->desc->group_name_prefix,
				statg->idx,
				desc->name, 0, "g");
	} else {
		return osmo_stats_reporter_statsd_send(srep,
			statg->desc->group_name_prefix,
			statg->idx,
			desc->name, value, "g");
	}
}
#endif /* !EMBEDDED */

/* @} */
