/*
 * Copyright Runtime.io 2018. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <zephyr/types.h>
#include <zephyr/stats/stats.h>

#define STATS_GEN_NAME_MAX_LEN  (sizeof("s255"))

/* The global list of registered statistic groups. */
static struct stats_hdr *stats_list;

static const char *
stats_get_name(const struct stats_hdr *hdr, int idx)
{
#ifdef CONFIG_STATS_NAMES
	const struct stats_name_map *cur;
	uint16_t off;
	int i;

	/* The stats name map contains two elements, an offset into the
	 * statistics entry structure, and the name corresponding to that
	 * offset.  This annotation allows for naming only certain statistics,
	 * and doesn't enforce ordering restrictions on the stats name map.
	 */
	off = sizeof(*hdr) + idx * hdr->s_size;
	for (i = 0; i < hdr->s_map_cnt; i++) {
		cur = hdr->s_map + i;
		if (cur->snm_off == off) {
			return cur->snm_name;
		}
	}
#endif

	return NULL;
}

static uint16_t
stats_get_off(const struct stats_hdr *hdr, int idx)
{
	return (uint16_t) (sizeof(*hdr) + idx * (int) hdr->s_size);
}

/**
 * Creates a generic name for an unnamed stat.  The name has the form:
 *     s<idx>
 *
 * This function assumes the supplied destination buffer is large enough to
 * accommodate the name.
 */
static void
stats_gen_name(int idx, char *dst)
{
	char c;
	int len;
	int i;

	/* Encode the stat name backwards (e.g., "321s" for index 123). */
	len = 0;
	do {
		dst[len++] = '0' + idx % 10;
		idx /= 10;
	} while (idx > 0);
	dst[len++] = 's';

	/* Reverse the string to its proper order. */
	for (i = 0; i < len / 2; i++) {
		c = dst[i];
		dst[i] = dst[len - i - 1];
		dst[len - i - 1] = c;
	}
	dst[len] = '\0';
}

/**
 * Walk a specific statistic entry, and call walk_func with arg for
 * each field within that entry.
 *
 * Walk func takes the following parameters:
 *
 * - The header of the statistics section (stats_hdr)
 * - The user supplied argument
 * - The name of the statistic (if STATS_NAME_ENABLE = 0, this is
 *   ("s%d", n), where n is the number of the statistic in the structure.
 * - A pointer to the current entry.
 *
 * @return 0 on success, the return code of the walk_func on abort.
 *
 */
int
stats_walk(struct stats_hdr *hdr, stats_walk_fn *walk_func, void *arg)
{
	const char *name;
	char name_buf[STATS_GEN_NAME_MAX_LEN];
	int rc;
	int i;

	for (i = 0; i < hdr->s_cnt; i++) {
		name = stats_get_name(hdr, i);
		if (name == NULL) {
			/* No assigned name; generate a temporary s<#> name. */
			stats_gen_name(i, name_buf);
			name = name_buf;
		}

		rc = walk_func(hdr, arg, name, stats_get_off(hdr, i));
		if (rc != 0) {
			return rc;
		}
	}

	return 0;
}

/**
 * Initialize a statistics structure, pointed to by hdr.
 *
 * @param hdr The header of the statistics structure, contains things
 *            like statistic section name, size of statistics entries,
 *            number of statistics, etc.
 * @param size The size of the individual statistics elements, either
 *             2 (16-bits), 4 (32-bits) or 8 (64-bits).
 * @param cnt The number of elements in the statistics structure
 * @param map The mapping of statistics name to statistic entry
 * @param map_cnt The number of items in the statistics map
 */
void
stats_init(struct stats_hdr *hdr, uint8_t size, uint16_t cnt,
	   const struct stats_name_map *map, uint16_t map_cnt)
{
	hdr->s_size = size;
	hdr->s_cnt = cnt;
#ifdef CONFIG_STATS_NAMES
	hdr->s_map = map;
	hdr->s_map_cnt = map_cnt;
#endif

	stats_reset(hdr);
}

/**
 * Walk the group of registered statistics and call walk_func() for
 * each element in the list.  This function _DOES NOT_ lock the statistics
 * list, and assumes that the list is not being changed by another task.
 * (assumption: all statistics are registered prior to OS start.)
 *
 * @param walk_func The walk function to call, with a statistics header
 *                  and arg.
 * @param arg The argument to call the walk function with.
 *
 * @return 0 on success, non-zero error code on failure
 */
int
stats_group_walk(stats_group_walk_fn *walk_func, void *arg)
{
	struct stats_hdr *hdr;
	int rc;

	for (hdr = stats_list; hdr != NULL; hdr = hdr->s_next) {
		rc = walk_func(hdr, arg);
		if (rc != 0) {
			return rc;
		}
	}

	return 0;
}

struct stats_hdr *
stats_group_get_next(const struct stats_hdr *cur)
{
	if (cur == NULL) {
		return stats_list;
	}

	/* Cast away const. */
	return cur->s_next;
}

/**
 * Find a statistics structure by name, this is not thread-safe.
 * (assumption: all statistics are registered prior ot OS start.)
 *
 * @param name The statistic structure name to find
 *
 * @return statistic structure if found, NULL if not found.
 */
struct stats_hdr *
stats_group_find(const char *name)
{
	struct stats_hdr *hdr;

	for (hdr = stats_list; hdr != NULL; hdr = hdr->s_next) {
		if (strcmp(hdr->s_name, name) == 0) {
			return hdr;
		}
	}

	return NULL;
}

/**
 * Register the statistics pointed to by shdr, with the name of "name."
 *
 * @param name The name of the statistic to register.  This name is guaranteed
 *             unique in the statistics map.  If already exists, this function
 *             will return an error.
 * @param shdr The statistics header to register into the statistic map under
 *             name.
 *
 * @return 0 on success, non-zero error code on failure.
 */
int
stats_register(const char *name, struct stats_hdr *hdr)
{
	struct stats_hdr *prev;
	struct stats_hdr *cur;

	/* Don't allow duplicate entries. */
	prev = NULL;
	for (cur = stats_list; cur != NULL; cur = cur->s_next) {
		if (strcmp(cur->s_name, name) == 0) {
			return -EALREADY;
		}

		prev = cur;
	}

	if (prev == NULL) {
		stats_list = hdr;
	} else {
		prev->s_next = hdr;
	}
	hdr->s_name = name;

	return 0;
}

/**
 * Initializes and registers the specified statistics section.
 *
 * @param shdr The statistics header to register
 * @param size The entry size of the statistics to register either 2 (16-bit),
 *             4 (32-bit) or 8 (64-bit).
 * @param cnt  The number of statistics entries in the statistics structure.
 * @param map  The map of statistics entry to statistics name, only used when
 *             STATS_NAMES is enabled.
 * @param map_cnt The number of elements in the statistics name map.
 * @param name The name of the statistics element to register with the system.
 *
 * @return 0 on success, non-zero error code on failure.
 */
int
stats_init_and_reg(struct stats_hdr *shdr, uint8_t size, uint16_t cnt,
		   const struct stats_name_map *map, uint16_t map_cnt,
		   const char *name)
{
	int rc;

	stats_init(shdr, size, cnt, map, map_cnt);

	rc = stats_register(name, shdr);
	if (rc != 0) {
		return rc;
	}

	return 0;
}

/**
 * Resets and zeroes the specified statistics section.
 *
 * @param shdr The statistics header to zero
 */
void
stats_reset(struct stats_hdr *hdr)
{
	(void)memset((uint8_t *)hdr + sizeof(*hdr), 0, hdr->s_size * hdr->s_cnt);
}
