/*****************************************************************************\
 *  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;
}

/*
 * Check if a parser was already built from this plugin
 * IN parsers - parsers built so far
 * IN count - number of populated entries in parsers
 * IN plugin_offset - resolved plugin index of the candidate
 * RET true if this plugin already has a parser
 *
 * Parameters are deliberately not compared. Only the version reaches a
 * {data_parser} URL, so every parser built from one plugin resolves to the
 * same path and only the first can be served.
 */
static bool _duplicate_parser(data_parser_t **parsers, int count,
			      int plugin_offset)
{
	for (int i = 0; i < count; i++)
		if (parsers[i]->plugin_offset == plugin_offset)
			return true;

	return false;
}

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, count = 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;
	}

	/*
	 * Several requested parsers can share one loaded plugin, as a
	 * version and each of its "+params" variants all resolve to the
	 * same plugin. Sizing by plugins->count then leaves no room for
	 * the NULL terminator and every walk of the array reads past its
	 * end. Size by whichever count is larger.
	 */
	for (int j = 0; pparams && pparams[j].plugin_type; j++)
		count++;

	if (count < plugins->count)
		count = plugins->count;

	parsers = xcalloc((count + 1), sizeof(*parsers));

	if (pparams) {
		int n = 0;

		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;
			}

			/*
			 * A version and LATEST_PLUGIN_NAME name the same
			 * parser, so one can be requested twice. Asking for it
			 * twice is not an error, but building it twice is:
			 * callers bind one parser per version.
			 */
			if (_duplicate_parser(parsers, n, index)) {
				log_flag(DATA, "%s: skipping repeat request for plugin %s",
					 __func__, plugins->types[index]);
				xfree(pparams[i].params);
				xfree(pparams[i].plugin_type);
				continue;
			}

			parsers[n++] =
				_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 < 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);
}
