/*! \file talloc_ctx_vty.c
 * Osmocom talloc context introspection via VTY. */
/*
 * (C) 2017 by Vadim Yanitskiy <axilirator@gmail.com>
 *
 * 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 <stdio.h>
#include <regex.h>
#include <string.h>
#include <talloc.h>

#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>

extern void *tall_vty_ctx;
extern struct host host;

enum walk_filter_type {
	WALK_FILTER_NONE = 0,
	WALK_FILTER_REGEXP,
	WALK_FILTER_TREE,
};

struct walk_cb_params {
	enum walk_filter_type filter;
	unsigned int depth_pass;
	const void *chunk_ptr;
	struct vty *vty;
	regex_t regexp;
};

/*!
 * Print a talloc memory hierarchy to the given VTY.
 * To be called by the talloc_report_depth_cb().
 * If one of supported filters is specified, then
 * only satisfying memory trees would be printed.
 *
 * @param chunk     The talloc chunk to be printed
 * @param depth     Current depth value
 * @param max_depth Maximal depth of report (negative means full)
 * @param is_ref    Is this chunk a reference?
 * @param data      The walk_cb_params struct instance
 */
static void talloc_ctx_walk_cb(const void *chunk, int depth,
	int max_depth, int is_ref, void *data)
{
	struct walk_cb_params *p = (struct walk_cb_params *) data;
	const char *chunk_name = talloc_get_name(chunk);
	struct vty *vty = p->vty;
	size_t chunk_blocks;
	size_t chunk_size;
	int rc;

	if (depth > 0 && p->filter) {
		/**
		 * A filter is being bypassed while current depth value
		 * is higher than the 'depth_pass', i.e. the callback does
		 * processing the child memory chunks. As soon as this
		 * condition becomes false, we need to 'enable' a filter,
		 * and resume the processing other chunks.
		 */
		if (p->depth_pass && depth > p->depth_pass)
			goto filter_bypass;
		else
			p->depth_pass = 0;

		switch (p->filter) {
		case WALK_FILTER_REGEXP:
			/* Filter chunks using a regular expression */
			rc = regexec(&p->regexp, chunk_name, 0, NULL, 0);
			if (rc)
				return;
			break;
		case WALK_FILTER_TREE:
			/* Print a specific memory tree only */
			if (chunk != p->chunk_ptr)
				return;
			break;
		default:
			/* Unsupported filter or incorrect value */
			return;
		}

		/**
		 * As soon as a filter passes any chunk, all the memory
		 * tree starting from one would be printed. To do that,
		 * we need to temporary 'disable' a filter for child
		 * chunks (current_depth > depth_pass).
		 */
		p->depth_pass = depth;
	}

filter_bypass:

	if (is_ref) {
		vty_out(vty, "%*sreference to: %s%s",
			depth * 2, "", chunk_name, VTY_NEWLINE);
		return;
	}

	chunk_blocks = talloc_total_blocks(chunk);
	chunk_size = talloc_total_size(chunk);

	if (depth == 0) {
		vty_out(vty, "%stalloc report on '%s' "
			"(total %6zu bytes in %3zu blocks)%s",
			(max_depth < 0 ? "full " : ""), chunk_name,
			chunk_size, chunk_blocks, VTY_NEWLINE);
		return;
	}

	vty_out(vty, "%*s%-30s contains %6zu bytes "
		"in %3zu blocks (ref %zu) %p%s", depth * 2, "",
		chunk_name, chunk_size, chunk_blocks,
		talloc_reference_count(chunk),
		chunk, VTY_NEWLINE);
}

/*!
 * Parse talloc context and depth values from a VTY command.
 *
 * @param ctx    The context to be printed (a string from argv)
 * @param depth  The report depth (a string from argv)
 * @param params The walk_cb_params struct instance
 */
static void talloc_ctx_walk(const char *ctx, const char *depth,
	struct walk_cb_params *params)
{
	const void *talloc_ctx = NULL;
	int max_depth;

	/* Determine a context for report */
	if (!strncmp(ctx, "app", 3))
		talloc_ctx = host.app_info->tall_ctx;
	else if (!strncmp(ctx, "all", 3))
		talloc_ctx = NULL;

	/* Determine report depth */
	if (depth[0] == 'f')
		max_depth = -1;
	else if (depth[0] == 'b')
		max_depth = 1;
	else
		max_depth = atoi(depth);

	talloc_report_depth_cb(talloc_ctx, 0, max_depth,
		&talloc_ctx_walk_cb, params);
}

#define BASE_CMD_STR \
	"show talloc-context (application|all) (full|brief|DEPTH)"

#define BASE_CMD_DESCR \
	SHOW_STR "Show talloc memory hierarchy\n" \
	"Application's context\n" \
	"All contexts, if NULL-context tracking is enabled\n" \
	"Display a full talloc memory hierarchy\n" \
	"Display a brief talloc memory hierarchy\n" \
	"Specify required maximal depth value"

DEFUN(show_talloc_ctx, show_talloc_ctx_cmd,
	BASE_CMD_STR, BASE_CMD_DESCR)
{
	struct walk_cb_params *params;

	/* Allocate memory */
	params = talloc_zero(tall_vty_ctx, struct walk_cb_params);
	if (!params)
		return CMD_WARNING;

	/* Set up callback parameters */
	params->filter = WALK_FILTER_NONE;
	params->vty = vty;

	talloc_ctx_walk(argv[0], argv[1], params);

	/* Free memory */
	talloc_free(params);

	return CMD_SUCCESS;
}

DEFUN(show_talloc_ctx_filter, show_talloc_ctx_filter_cmd,
	BASE_CMD_STR " filter REGEXP", BASE_CMD_DESCR
	"Filter chunks using regular expression\n"
	"Regular expression")
{
	struct walk_cb_params *params;
	int rc;

	/* Allocate memory */
	params = talloc_zero(tall_vty_ctx, struct walk_cb_params);
	if (!params)
		return CMD_WARNING;

	/* Attempt to compile a regular expression */
	rc = regcomp(&params->regexp, argv[2], 0);
	if (rc) {
		vty_out(vty, "Invalid expression%s", VTY_NEWLINE);
		talloc_free(params);
		return CMD_WARNING;
	}

	/* Set up callback parameters */
	params->filter = WALK_FILTER_REGEXP;
	params->vty = vty;

	talloc_ctx_walk(argv[0], argv[1], params);

	/* Free memory */
	regfree(&params->regexp);
	talloc_free(params);

	return CMD_SUCCESS;
}

DEFUN(show_talloc_ctx_tree, show_talloc_ctx_tree_cmd,
	BASE_CMD_STR " tree ADDRESS", BASE_CMD_DESCR
	"Display only a specific memory chunk\n"
	"Chunk address (e.g. 0xdeadbeef)")
{
	struct walk_cb_params *params;
	int rc;

	/* Allocate memory */
	params = talloc_zero(tall_vty_ctx, struct walk_cb_params);
	if (!params)
		return CMD_WARNING;

	/* Attempt to parse an address */
	rc = sscanf(argv[2], "%p", &params->chunk_ptr);
	if (rc != 1) {
		vty_out(vty, "Invalid chunk address%s", VTY_NEWLINE);
		talloc_free(params);
		return CMD_WARNING;
	}

	/* Set up callback parameters */
	params->filter = WALK_FILTER_TREE;
	params->vty = vty;

	talloc_ctx_walk(argv[0], argv[1], params);

	/* Free memory */
	talloc_free(params);

	return CMD_SUCCESS;
}

/*!
 * Install VTY commands for talloc context introspection.
 *
 * This installs a set of VTY commands for introspection of
 * a talloc context. Call this once from your application
 * if you want to support those commands.
 */
void osmo_talloc_vty_add_cmds(void)
{
	install_element_ve(&show_talloc_ctx_cmd);
	install_element_ve(&show_talloc_ctx_tree_cmd);
	install_element_ve(&show_talloc_ctx_filter_cmd);
}
