/*****************************************************************************\
 *  data.h - data_t parser plugin interface
 ******************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm 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.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm 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 Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "config.h"

#include "src/common/data.h"
#include "src/common/fd.h"
#include "src/common/list.h"
#include "src/common/log.h"
#include "src/common/openapi.h"
#include "src/common/read_config.h"
#include "src/common/timers.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "src/interfaces/data_parser.h"
#include "src/interfaces/serializer.h"

#define PARSE_MAJOR_TYPE "data_parser"
#define PARSE_MAGIC 0x0ea0b1be
#define LATEST_PLUGIN_NAME "latest"

typedef struct data_parser_s {
	int magic;
	int plugin_offset;
	/* opaque context returned by the plugin's new() */
	void *plugin_ctxt;
	/* on_error callback arg from _new() - shallow pointer */
	void *error_arg;
	/* on_warn callback arg from _new() - shallow pointer */
	void *warn_arg;
	const char *plugin_type; /* ptr to plugin plugin_type - do not xfree */
	char *params; /* parameters from _new - must xfree */
	char *plugin_string; /* plugin_type+params - must xfree */
} data_parser_t;

typedef struct {
	int (*parse)(void *arg, data_parser_type_t type, void *dst,
		     ssize_t dst_bytes, data_t *src, data_t *parent_path);
	int (*dump)(void *arg, data_parser_type_t type, void *src,
		    ssize_t src_bytes, data_t *dst);
	/* ptr returned to be handed to commands as arg */
	void *(*new)(data_parser_on_error_t on_parse_error,
		     data_parser_on_error_t on_dump_error,
		     data_parser_on_error_t on_query_error, void *error_arg,
		     data_parser_on_warn_t on_parse_warn,
		     data_parser_on_warn_t on_dump_warn,
		     data_parser_on_warn_t on_query_warn, void *warn,
		     char *params);
	void (*free)(void *arg);
	int (*assign)(void *arg, data_parser_attr_type_t type, void *obj);
	openapi_type_t (*resolve_openapi_type)(void *arg,
					       data_parser_type_t type,
					       const char *field);
	const char *(*resolve_type_str)(void *arg, data_parser_type_t type);
	int (*inc_ref)(void *arg, data_parser_type_t type,
		       void **references_ptr);
	int (*populate_schema)(void *arg, data_parser_type_t type,
		       void **references_ptr, data_t *dst, data_t *schemas);
	int (*populate_parameters)(void *arg, data_parser_type_t parameter_type,
				   data_parser_type_t query_type,
				   void **references_ptr, data_t *dst,
				   data_t *schemas);
	void (*release_refs)(void *arg, void **references_ptr);
	bool (*is_complex)(void *arg);
	bool (*is_deprecated)(void *arg);
	int (*dump_flags)(void *arg, data_t *dst);
} parse_funcs_t;

typedef struct {
	char *plugin_type;
	char *params;
} plugin_param_t;

/*
 * Must be synchronized with parse_funcs_t above.
 */
static const char *parse_syms[] = {
	"data_parser_p_parse",
	"data_parser_p_dump",
	"data_parser_p_new",
	"data_parser_p_free",
	"data_parser_p_assign",
	"data_parser_p_resolve_openapi_type",
	"data_parser_p_resolve_type_string",
	"data_parser_p_increment_reference",
	"data_parser_p_populate_schema",
	"data_parser_p_populate_parameters",
	"data_parser_p_release_references",
	"data_parser_p_is_complex",
	"data_parser_p_is_deprecated",
	"data_parser_p_dump_flags",
};

static plugins_t *plugins = NULL;
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
static int active_parsers = 0;

static const char *_get_plugin_version(const char *plugin_type);

extern int data_parser_g_parse(data_parser_t *parser, data_parser_type_t type,
			       void *dst, ssize_t dst_bytes, data_t *src,
			       data_t *parent_path)
{
	const parse_funcs_t *funcs;
	DEF_TIMERS;
	int rc;

	if (!parser)
		return ESLURM_DATA_INVALID_PARSER;

	funcs = plugins->functions[parser->plugin_offset];

	if (!src || (data_get_type(src) == DATA_TYPE_NONE))
		return ESLURM_DATA_PARSE_NOTHING;

	xassert(type > DATA_PARSER_TYPE_INVALID);
	xassert(type < DATA_PARSER_TYPE_MAX);
	xassert(parser->magic == PARSE_MAGIC);
	xassert(data_get_type(parent_path) == DATA_TYPE_LIST);
	xassert(plugins && (plugins->magic == PLUGINS_MAGIC));
	xassert(parser->plugin_offset < plugins->count);
	xassert(plugins->functions[parser->plugin_offset]);

	START_TIMER;
	rc = funcs->parse(parser->plugin_ctxt, type, dst, dst_bytes, src,
			  parent_path);
	END_TIMER2(__func__);

	return rc;
}

extern int data_parser_g_dump(data_parser_t *parser, data_parser_type_t type,
			      void *src, ssize_t src_bytes, data_t *dst)
{
	DEF_TIMERS;
	int rc;
	const parse_funcs_t *funcs;

	if (!parser)
		return ESLURM_DATA_INVALID_PARSER;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(data_get_type(dst));
	xassert(type > DATA_PARSER_TYPE_INVALID);
	xassert(type < DATA_PARSER_TYPE_MAX);
	xassert(parser->magic == PARSE_MAGIC);
	xassert(plugins && (plugins->magic == PLUGINS_MAGIC));
	xassert(parser->plugin_offset < plugins->count);
	xassert(plugins->functions[parser->plugin_offset]);

	START_TIMER;
	rc = funcs->dump(parser->plugin_ctxt, type, src, src_bytes, dst);
	END_TIMER2(__func__);

	return rc;
}

/* takes ownership of params */
static data_parser_t *_new_parser(data_parser_on_error_t on_parse_error,
				  data_parser_on_error_t on_dump_error,
				  data_parser_on_error_t on_query_error,
				  void *error_arg,
				  data_parser_on_warn_t on_parse_warn,
				  data_parser_on_warn_t on_dump_warn,
				  data_parser_on_warn_t on_query_warn,
				  void *warn_arg, int plugin_index,
				  char *params)
{
	DEF_TIMERS;
	const parse_funcs_t *funcs;
	data_parser_t *parser = xmalloc(sizeof(*parser));

	parser->magic = PARSE_MAGIC;

	parser->plugin_offset = plugin_index;
	parser->plugin_type = plugins->types[plugin_index];
	parser->params = params;
	parser->error_arg = error_arg;
	parser->warn_arg = warn_arg;

	START_TIMER;
	funcs = plugins->functions[plugin_index];
	parser->plugin_ctxt =
		funcs->new (on_parse_error, on_dump_error, on_query_error,
			    error_arg, on_parse_warn, on_dump_warn,
			    on_query_warn, warn_arg, params);
	xstrfmtcat(parser->plugin_string, "%s%s", parser->plugin_type,
		   (parser->params ? parser->params : ""));
	END_TIMER2(__func__);

	slurm_mutex_lock(&init_mutex);
	xassert(active_parsers >= 0);
	active_parsers++;
	slurm_mutex_unlock(&init_mutex);

	return parser;
}

static plugin_param_t *_parse_plugin_type(const char *plugin_type)
{
	char *type, *last = NULL, *pl;
	plugin_param_t *pparams = NULL;
	int count = 0;

	if (!plugin_type)
		return NULL;

	pl = xstrdup(plugin_type);
	type = strtok_r(pl, ",", &last);
	while (type) {
		char *pl;
		plugin_param_t *p;

		xrecalloc(pparams, (count + 2), sizeof(*pparams));

		p = &pparams[count];

		if ((pl = xstrstr(type,
				  SLURM_DATA_PARSER_PLUGIN_PARAMS_CHAR))) {
			p->plugin_type = xstrndup(type, (pl - type));
			p->params = xstrdup(pl);
		} else {
			p->plugin_type = xstrdup(type);
		}

		if (!xstrcasecmp(p->plugin_type, LATEST_PLUGIN_NAME)) {
			xfree(p->plugin_type);
			p->plugin_type = xstrdup(SLURM_DATA_PARSER_VERSION);
		}

		log_flag(DATA, "%s: plugin=%s params=%s",
		       __func__, p->plugin_type, p->params);

		count++;

		type = strtok_r(NULL, ",", &last);
	}

	xfree(pl);
	return pparams;
}

static int _load_plugins(plugin_param_t *pparams, plugrack_foreach_t listf,
			 bool skip_loading)
{
	int rc = SLURM_SUCCESS;

	if (skip_loading)
		return rc;

	slurm_mutex_lock(&init_mutex);

	serializer_required(MIME_TYPE_JSON);

	xassert(sizeof(parse_funcs_t) ==
		(sizeof(void *) * ARRAY_SIZE(parse_syms)));

	if (!pparams) {
		rc = load_plugins(&plugins, PARSE_MAJOR_TYPE, NULL, listf,
				  parse_syms, ARRAY_SIZE(parse_syms));
	} else {
		for (int i = 0; !rc && pparams[i].plugin_type; i++)
			rc = load_plugins(&plugins, PARSE_MAJOR_TYPE,
					  pparams[i].plugin_type, listf,
					  parse_syms, ARRAY_SIZE(parse_syms));
	}

	xassert(rc || plugins);

	slurm_mutex_unlock(&init_mutex);

	return rc;
}

static int _find_plugin_by_type(const char *plugin_type)
{
	if (!plugin_type || !plugins)
		return -1;

	/* quick match by pointer address */
	for (int i = 0; i < plugins->count; i++) {
		if (plugin_type == plugins->types[i])
			return i;
	}

	/* match by full string */
	for (int i = 0; i < plugins->count; i++) {
		if (!xstrcasecmp(plugin_type, plugins->types[i]))
			return i;
	}

	/* match by string without "data_parser/" */
	for (int i = 0; i < plugins->count; i++) {
		if (!xstrcasecmp(plugin_type,
				 _get_plugin_version(plugins->types[i])))
			return i;
	}

	return -1;
}

extern data_parser_t *data_parser_g_new(data_parser_on_error_t on_parse_error,
					data_parser_on_error_t on_dump_error,
					data_parser_on_error_t on_query_error,
					void *error_arg,
					data_parser_on_warn_t on_parse_warn,
					data_parser_on_warn_t on_dump_warn,
					data_parser_on_warn_t on_query_warn,
					void *warn_arg, const char *plugin_type,
					plugrack_foreach_t listf,
					bool skip_loading)
{
	int rc, index;
	char *params = NULL;
	data_parser_t *parser = NULL;
	plugin_param_t *pparams;

	if (!xstrcasecmp(plugin_type, "list")) {
		xassert(listf);
		load_plugins(&plugins, PARSE_MAJOR_TYPE, plugin_type, listf,
			     parse_syms, ARRAY_SIZE(parse_syms));
		return NULL;
	}

	pparams = _parse_plugin_type(plugin_type);

	if (!pparams || !pparams[0].plugin_type) {
		error("%s: invalid plugin %s", __func__, plugin_type);
		goto cleanup;
	}

	if (pparams[1].plugin_type) {
		error("%s: rejecting ambiguous plugin %s",
		      __func__, plugin_type);
		goto cleanup;
	}

	if ((rc = _load_plugins(pparams, listf, skip_loading))) {
		error("%s: failure loading plugins: %s",
		      __func__, slurm_strerror(rc));
		goto cleanup;
	}

	if ((index = _find_plugin_by_type(pparams[0].plugin_type)) < 0) {
		error("%s: unable to find plugin %s", __func__,
		      pparams[0].plugin_type);
		goto cleanup;
	}

	SWAP(params, pparams[0].params);

	parser = _new_parser(on_parse_error, on_dump_error, on_query_error,
			     error_arg, on_parse_warn, on_dump_warn,
			     on_query_warn, warn_arg, index, params);
cleanup:
	if (pparams) {
		for (int i = 0; pparams[i].plugin_type; i++) {
			xfree(pparams[i].plugin_type);
			xfree(pparams[i].params);
		}
		xfree(pparams);
	}

	return parser;
}

extern data_parser_t **data_parser_g_new_array(
	data_parser_on_error_t on_parse_error,
	data_parser_on_error_t on_dump_error,
	data_parser_on_error_t on_query_error,
	void *error_arg,
	data_parser_on_warn_t on_parse_warn,
	data_parser_on_warn_t on_dump_warn,
	data_parser_on_warn_t on_query_warn,
	void *warn_arg,
	const char *plugin_type,
	plugrack_foreach_t listf,
	bool skip_loading)
{
	int rc, i = 0;
	data_parser_t **parsers = NULL;
	plugin_param_t *pparams;

	if (!xstrcasecmp(plugin_type, "list")) {
		xassert(listf);
		load_plugins(&plugins, PARSE_MAJOR_TYPE, plugin_type, listf,
			     parse_syms, ARRAY_SIZE(parse_syms));
		return NULL;
	}

	pparams = _parse_plugin_type(plugin_type);

	if ((rc = _load_plugins(pparams, listf, skip_loading))) {
		error("%s: failure loading plugins: %s",
		      __func__, slurm_strerror(rc));
		goto cleanup;
	}

	/* always allocate for all possible plugins */
	parsers = xcalloc((plugins->count + 1), sizeof(*parsers));

	if (pparams) {
		for (; pparams[i].plugin_type; i++) {
			int index =
				_find_plugin_by_type(pparams[i].plugin_type);

			if (index < 0) {
				error("%s: unable to find plugin %s",
				      __func__, pparams[i].plugin_type);
				goto cleanup;
			}

			parsers[i] = _new_parser(on_parse_error, on_dump_error,
						 on_query_error, error_arg,
						 on_parse_warn, on_dump_warn,
						 on_query_warn, warn_arg, index,
						 pparams[i].params);

			pparams[i].params = NULL;
			xfree(pparams[i].plugin_type);
		}
	} else {
		for (; i < plugins->count; i++) {
			parsers[i] = _new_parser(on_parse_error, on_dump_error,
						 on_query_error, error_arg,
						 on_parse_warn, on_dump_warn,
						 on_query_warn, warn_arg, i,
						 NULL);
		}
	}

	xfree(pparams);

	return parsers;
cleanup:
	if (pparams) {
		for (; pparams[i].plugin_type; i++) {
			xfree(pparams[i].plugin_type);
			xfree(pparams[i].params);
		}
		xfree(pparams);
	}

	if (plugins && parsers)
		for (int j = 0; j < plugins->count; j++)
			FREE_NULL_DATA_PARSER(parsers[j]);
	xfree(parsers);

	return NULL;
}

extern const char *data_parser_get_plugin(data_parser_t *parser)
{
	if (!parser)
		return NULL;

	xassert(parser->magic == PARSE_MAGIC);

	return parser->plugin_string;
}

extern void *data_parser_get_error_arg(data_parser_t *parser)
{
	if (!parser)
		return NULL;

	xassert(parser->magic == PARSE_MAGIC);

	return parser->error_arg;
}

extern void *data_parser_get_warn_arg(data_parser_t *parser)
{
	if (!parser)
		return NULL;

	xassert(parser->magic == PARSE_MAGIC);

	return parser->warn_arg;
}

static const char *_get_plugin_version(const char *plugin_type)
{
	static const char prefix[] = PARSE_MAJOR_TYPE "/";

#ifndef NDEBUG
	/* catch if the prefix ever changes in an unexpected way */
	const char *match;
	xassert(plugin_type);
	match = xstrstr(plugin_type, prefix);
	xassert(match);
#endif

	return plugin_type + strlen(prefix);
}

extern const char *data_parser_get_plugin_version(data_parser_t *parser)
{
	xassert(!parser || parser->magic == PARSE_MAGIC);

	if (!parser)
		return NULL;

	return _get_plugin_version(parser->plugin_type);
}

extern const char *data_parser_get_plugin_params(data_parser_t *parser)
{
	xassert(!parser || parser->magic == PARSE_MAGIC);

	if (!parser)
		return NULL;

	return parser->params;
}

extern void data_parser_g_free(data_parser_t *parser, bool skip_unloading)
{
	DEF_TIMERS;
	const parse_funcs_t *funcs;

	if (!parser)
		return;

	funcs = plugins->functions[parser->plugin_offset];

	if (plugins) {
		xassert(plugins->magic == PLUGINS_MAGIC);
		xassert(plugins->functions[parser->plugin_offset]);
		xassert(parser->magic == PARSE_MAGIC);
		xassert(parser->plugin_offset < plugins->count);
	}

	START_TIMER;
	if (plugins)
		funcs->free(parser->plugin_ctxt);
	END_TIMER2(__func__);

	xfree(parser->params);
	xfree(parser->plugin_string);
	parser->plugin_ctxt = NULL;
	parser->plugin_offset = -1;
	parser->magic = ~PARSE_MAGIC;
	xfree(parser);

	slurm_mutex_lock(&init_mutex);
	xassert(active_parsers >= 0);
	active_parsers--;
	xassert(active_parsers >= 0);

	if (!skip_unloading && !active_parsers)
		FREE_NULL_PLUGINS(plugins);
	slurm_mutex_unlock(&init_mutex);
}

extern void data_parser_g_array_free(data_parser_t **ptr, bool skip_unloading)
{
	if (!ptr)
		return;

	for (int i = 0; ptr[i]; i++)
		data_parser_g_free(ptr[i], skip_unloading);

	xfree(ptr);
}

extern int data_parser_g_assign(data_parser_t *parser,
				data_parser_attr_type_t type, void *obj)
{
	int rc;
	DEF_TIMERS;
	const parse_funcs_t *funcs;

	if (!parser)
		return ESLURM_DATA_INVALID_PARSER;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser);
	xassert(plugins);
	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);
	xassert(type > DATA_PARSER_ATTR_INVALID);
	xassert(type < DATA_PARSER_ATTR_MAX);

	START_TIMER;
	rc = funcs->assign(parser->plugin_ctxt, type, obj);
	END_TIMER2(__func__);

	return rc;
}

extern openapi_resp_meta_t *data_parser_cli_meta(int argc, char **argv,
						 const char *mime_type)
{
	openapi_resp_meta_t *meta = xmalloc_nz(sizeof(*meta));
	int tty;
	char **argvnt = NULL;

	/* need a new array with a NULL terminator */
	if (argc > 0) {
		argvnt = xcalloc((argc + 1), sizeof(*argv));
		memcpy(argvnt, argv, (sizeof(*argv) * argc));
	}

	if (isatty(STDIN_FILENO))
		tty = STDIN_FILENO;
	else if (isatty(STDOUT_FILENO))
		tty = STDOUT_FILENO;
	else if (isatty(STDERR_FILENO))
		tty = STDERR_FILENO;
	else
		tty = -1;

	*meta = (openapi_resp_meta_t) {
		.plugin = {
			.data_parser = NULL,
			.accounting_storage =
				xstrdup(slurm_conf.accounting_storage_type),
		},
		.command = argvnt,
		.client = {
			.source = ((tty != -1) ? fd_resolve_path(tty) :
				   NULL),
			.uid = getuid(),
			.gid = getgid(),
		},
		.slurm = {
			.version = {
				.major = xstrdup(SLURM_MAJOR),
				.micro = xstrdup(SLURM_MICRO),
				.minor = xstrdup(SLURM_MINOR),
			},
			.release = xstrdup(SLURM_VERSION_STRING),
			.cluster = xstrdup(slurm_conf.cluster_name),
		}
	};

	return meta;
}

extern int data_parser_g_resolve_openapi_type(data_parser_t *parser,
					      data_parser_type_t type,
					      const char *field)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return OPENAPI_TYPE_INVALID;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser);
	xassert(plugins);
	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->resolve_openapi_type(parser->plugin_ctxt, type, field);
}

extern const char *data_parser_g_resolve_type_string(data_parser_t *parser,
						     data_parser_type_t type)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return NULL;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(plugins);
	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->resolve_type_str(parser->plugin_ctxt, type);
}

extern int data_parser_g_increment_reference(data_parser_t *parser,
					     data_parser_type_t type,
					     void **references_ptr)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return EINVAL;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->inc_ref(parser->plugin_ctxt, type, references_ptr);
}

extern int data_parser_g_populate_schema(data_parser_t *parser,
					 data_parser_type_t type,
					 void **references_ptr, data_t *dst,
					 data_t *schemas)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return EINVAL;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->populate_schema(parser->plugin_ctxt, type, references_ptr,
				      dst, schemas);
}

extern int data_parser_g_populate_parameters(data_parser_t *parser,
					     data_parser_type_t parameter_type,
					     data_parser_type_t query_type,
					     void **references_ptr, data_t *dst,
					     data_t *schemas)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return EINVAL;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->populate_parameters(parser->plugin_ctxt, parameter_type,
					  query_type, references_ptr, dst,
					  schemas);
}

extern void data_parser_g_release_references(data_parser_t *parser,
					     void **references_ptr)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->release_refs(parser->plugin_ctxt, references_ptr);
}

extern bool data_parser_g_is_complex(data_parser_t *parser)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return false;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->is_complex(parser->plugin_ctxt);
}

extern bool data_parser_g_is_deprecated(data_parser_t *parser)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return true;

	funcs = plugins->functions[parser->plugin_offset];

	xassert(parser->magic == PARSE_MAGIC);
	xassert(parser->plugin_offset < plugins->count);

	return funcs->is_deprecated(parser->plugin_ctxt);
}

extern int data_parser_g_dump_flags(data_parser_t *parser, data_t *dst)
{
	const parse_funcs_t *funcs;

	if (!parser)
		return EINVAL;

	xassert(data_get_type(dst));
	xassert(parser->magic == PARSE_MAGIC);
	xassert(plugins && (plugins->magic == PLUGINS_MAGIC));
	xassert(parser->plugin_offset < plugins->count);
	xassert(plugins->functions[parser->plugin_offset]);

	funcs = plugins->functions[parser->plugin_offset];

	return funcs->dump_flags(parser->plugin_ctxt, dst);
}
