/*****************************************************************************\
 *  openapi.c - Slurm data parser openapi specifier
 *****************************************************************************
 *  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 "src/common/data.h"
#include "src/common/http.h"
#include "src/common/log.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "api.h"
#include "openapi.h"
#include "parsers.h"
#include "parsing.h"

#define MAGIC_SPEC_ARGS 0xa891beab
#define REF_PATH OPENAPI_PATH_REL OPENAPI_SCHEMAS_PATH
#define TYPE_PREFIX "DATA_PARSER_"
#define KEY_PREFIX XSTRINGIFY(DATA_VERSION) "_"
#define IS_FLAG_BIT_DEPRECATED(bit, args) \
	(bit->deprecated || data_parser_p_is_deprecated(args->args))
#define IS_PARSER_DEPRECATED(parser, args) \
	(parser->deprecated || data_parser_p_is_deprecated(args->args))

typedef struct {
	int magic; /* MAGIC_SPEC_ARGS */
	args_t *args;
	const parser_t *parsers;
	int parser_count;
	data_t *paths; /* existing paths in OAS */
	data_t *new_paths; /* newly populated paths */
	data_t *schemas;
	data_t *spec;
	data_t *path_params; /* dict of each path param */
	data_t *params; /* current parameters target */
	int *references; /* references[i] = count(parsers[i]) */
	bool disable_refs;
} spec_args_t;

#define MAGIC_REFS_PTR 0xaa910e8b

typedef struct {
	int magic; /* MAGIC_REFS_PTR */
	int *references; /* references[i] = count(parsers[i]) */
} refs_ptr_t;

static void _replace_refs(data_t *data, spec_args_t *sargs);
static void _count_refs(data_t *data, spec_args_t *sargs);
extern void _set_ref(data_t *obj, const parser_t *parent,
		     const parser_t *parser, spec_args_t *sargs);
static data_t *_resolve_parser_key(const parser_t *parser, data_t *dst);

static uint32_t _resolve_parser_index(const parser_t *parser,
				      spec_args_t *sargs)
{
	for (int i = 0; i < sargs->parser_count; i++)
		if (parser->type == sargs->parsers[i].type)
			return i;

	xassert(false);
	return NO_VAL;
}

static const parser_t *_resolve_parser(const char *type, spec_args_t *sargs)
{
	for (int i = 0; i < sargs->parser_count; i++)
		if (!xstrcmp(sargs->parsers[i].type_string, type))
			return &sargs->parsers[i];

	return NULL;
}

static char *_get_parser_key(const parser_t *parser)
{
	char *stype;
	char *key = NULL;

	check_parser(parser);
	xassert(!xstrncmp(parser->type_string, TYPE_PREFIX,
			  strlen(TYPE_PREFIX)));

	stype = xstrdup(parser->type_string + strlen(TYPE_PREFIX));
	xstrtolower(stype);
	xstrfmtcat(key, "%s%s", KEY_PREFIX, stype);
	xfree(stype);

	return key;
}

static char *_get_parser_path(const parser_t *parser)
{
	char *key = _get_parser_key(parser);
	char *path = NULL;

	xstrfmtcat(path, "%s%s", REF_PATH, key);
	xfree(key);

	return path;
}

/*
 * Populate OpenAPI specification field
 * IN obj - data_t ptr to specific field in OpenAPI schema
 * IN format - OpenAPI format to use
 * IN desc - Description of field to use (will take ownership)
 * RET ptr to "items" for ARRAY or "properties" for OBJECT or NULL
 */
static data_t *_set_openapi_props(data_t *obj, openapi_type_format_t format,
				  char *desc)
{
	data_t *dtype;
	const char *format_str;

	xassert(format > OPENAPI_FORMAT_INVALID);
	xassert(format < OPENAPI_FORMAT_MAX);

	if (data_get_type(obj) == DATA_TYPE_NULL)
		data_set_dict(obj);

	dtype = data_key_set(obj, "type");

	/* type may have already been set by _resolve_parser_key() */
	xassert((data_get_type(dtype) == DATA_TYPE_NULL) ||
		((data_get_type(dtype) == DATA_TYPE_STRING) &&
		 !xstrcmp(data_get_string(dtype), "object")));

	data_set_string(dtype, openapi_type_format_to_type_string(format));

	if ((format_str = openapi_type_format_to_format_string(format))) {
		data_t *dformat = data_key_set(obj, "format");
		xassert(data_get_type(dformat) == DATA_TYPE_NULL);
		data_set_string(dformat, format_str);
	}

	if (desc)
		data_set_string_own(data_key_set(obj, "description"), desc);

	if (format == OPENAPI_FORMAT_ARRAY)
		return data_set_dict(data_key_set(obj, "items"));

	if (format == OPENAPI_FORMAT_OBJECT)
		return data_set_dict(data_key_set(obj, "properties"));

	return NULL;
}

static bool _should_be_ref(const parser_t *parser, spec_args_t *sargs)
{
	uint32_t parser_index;

	if (sargs->disable_refs)
		return false;

	/*
	 * Removed parsers/fields are just place holders and using $ref will
	 * result in an invalid $ref include path.
	 */
	if (parser->model == PARSER_MODEL_REMOVED)
		return false;
	if (parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD)
		return false;

	parser_index = _resolve_parser_index(parser, sargs);

	/* parser with single reference doesn't need to be a $ref */
	if ((parser_index != NO_VAL) && !is_prefer_refs_mode(sargs->args)) {
		debug4("%s: %s references=%u",
		       __func__, parser->type_string,
		       sargs->references[parser_index]);

		if (sargs->references[parser_index] <= 1)
			return false;
	}

	if ((parser->obj_openapi == OPENAPI_FORMAT_OBJECT) ||
	    ((parser->obj_openapi == OPENAPI_FORMAT_ARRAY) &&
	     (parser->model != PARSER_MODEL_FLAG_ARRAY)))
		return true;

	if (parser->array_type || parser->pointer_type || parser->list_type ||
	    parser->fields || parser->alias_type)
		return true;

	return false;
}

static void _add_eflags(data_t *props, const parser_t *parser,
			spec_args_t *sargs)
{
	parser = find_parser_by_type(parser->type);

	for (int i = 0; i < parser->flag_bit_array_count; i++) {
		const flag_bit_t *bit = &parser->flag_bit_array[i];
		data_t *dchild;

		if (bit->hidden)
			continue;

		dchild = data_key_set(props, bit->name);
		_set_openapi_props(dchild, OPENAPI_FORMAT_BOOL, NULL);
	}
}

static void _add_field(data_t *obj, data_t *required,
		       const parser_t *const parent,
		       const parser_t *const pchild, spec_args_t *sargs)
{
	data_t *dchild;

	if (pchild->model == PARSER_MODEL_ARRAY_SKIP_FIELD)
		return;

	if (pchild->required)
		data_set_string(data_list_append(required), pchild->key);

	dchild = _resolve_parser_key(pchild, obj);

	if (pchild->model ==
	    PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) {
		data_t *p = data_key_get(dchild, "properties");
		_add_eflags(p, pchild, sargs);
	} else {
		_set_ref(dchild, parent, pchild, sargs);
	}
}

static void _add_param_flag_enum(data_t *param, const parser_t *parser)
{
	data_t *fenums = data_set_list(data_key_set(param, "enum"));
	data_set_string(data_key_set(param, "type"),
		openapi_type_format_to_type_string(OPENAPI_FORMAT_STRING));

	for (int i = 0; i < parser->flag_bit_array_count; i++)
		if (!parser->flag_bit_array[i].hidden)
			data_set_string(data_list_append(fenums),
					parser->flag_bit_array[i].name);
}

static void _gen_desc(char **desc_ptr, char **desc_at_ptr,
		      const parser_t *parser)
{
	bool has_key = (parser && parser->key && parser->key[0]);
	bool has_parser = (parser && parser->obj_desc && parser->obj_desc[0]);

	xassert(parser);

	if (!has_parser)
		return;

	if (has_key)
		_xstrfmtcatat(desc_ptr, desc_at_ptr, "%s", parser->obj_desc);
	else
		_xstrfmtcatat(desc_ptr, desc_at_ptr, "%s%s%s",
			      (*desc_ptr ? " (" : ""), parser->obj_desc,
			      (*desc_ptr ? ")" : ""));
}

/*
 * Populate OpenAPI specification field using parser
 * IN obj - data_t ptr to specific field in OpenAPI schema
 * IN parser - populate field with info from parser
 * IN description - description from parent pointer parser or NULL
 * IN deprecated - parser marked as deprecated
 *
 * RET ptr to "items" for ARRAY or "properties" for OBJECT or NULL
 */
static data_t *_set_openapi_parse(data_t *obj, const parser_t *parser,
				  spec_args_t *sargs, char *desc,
				  bool deprecated)
{
	data_t *props;
	openapi_type_format_t format;

	xassert(parser->magic == MAGIC_PARSER);
	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);
	xassert(parser->model != PARSER_MODEL_ARRAY_SKIP_FIELD);
	xassert(!parser->pointer_type);
	xassert(!parser->alias_type);
	xassert(parser->model != PARSER_MODEL_ARRAY_LINKED_FIELD);
	xassert(parser->model !=
		PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD);
	xassert(parser->model != PARSER_MODEL_ARRAY_REMOVED_FIELD);

	if (parser->array_type || parser->list_type ||
	    (parser->flag_bit_array && !parser->single_flag))
		format = OPENAPI_FORMAT_ARRAY;
	else if (parser->flag_bit_array && parser->single_flag)
		format = OPENAPI_FORMAT_STRING;
	else if (parser->fields)
		format = OPENAPI_FORMAT_OBJECT;
	else
		format = parser->obj_openapi;

	xassert(format > OPENAPI_FORMAT_INVALID);
	xassert(format < OPENAPI_FORMAT_MAX);

	if (!desc) {
		char *desc_at = NULL;
		_gen_desc(&desc, &desc_at, parser);
	}

	if ((props = _set_openapi_props(obj, format, desc))) {
		if (parser->array_type) {
			_set_ref(props, parser,
				 find_parser_by_type(parser->array_type),
				 sargs);
		} else if (parser->list_type) {
			_set_ref(props, parser,
				 find_parser_by_type(parser->list_type), sargs);
		} else if (parser->flag_bit_array) {
			_add_param_flag_enum(props, parser);
		} else if (parser->fields) {
			data_t *required =
				data_set_list(data_key_set(obj, "required"));

			for (int i = 0; i < parser->field_count; i++)
				_add_field(obj, required, parser,
					   &parser->fields[i], sargs);
		} else if (parser->model == PARSER_MODEL_REMOVED) {
			/* do nothing */
		} else if (!is_complex_mode(sargs->args)) {
			fatal("%s: parser %s need to provide openapi specification, array type or pointer type",
			      __func__, parser->type_string);
		}
	}

	if (deprecated)
		data_set_bool(data_key_set(obj, "deprecated"), true);

	return props;
}

extern void _set_ref(data_t *obj, const parser_t *parent,
		     const parser_t *parser, spec_args_t *sargs)
{
	char *str, *key;
	char *desc = NULL, *desc_at = NULL;
	bool deprecated = (parent && parent->deprecated);

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);

	while (true) {
		_gen_desc(&desc, &desc_at, parser);

		/* All children are deprecated once the parent is */
		if (parser->deprecated)
			deprecated = true;

		if (parser->model == PARSER_MODEL_REMOVED) {
			if (is_complex_mode(sargs->args))
				return;
			break;
		}

		if ((parser->model == PARSER_MODEL_ARRAY_LINKED_FIELD) ||
		    (parser->model ==
		     PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) ||
		    (parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD)) {
			/* resolve to linked parser */
			parent = parser;
			parser = find_parser_by_type(parser->type);

			continue;
		}

		if (parser->pointer_type) {
			parser = find_parser_by_type(parser->pointer_type);
			continue;
		}

		if (parser->alias_type) {
			parser = find_parser_by_type(parser->alias_type);
			continue;
		}

		break;
	}

	if (!_should_be_ref(parser, sargs)) {
		_set_openapi_parse(obj, parser, sargs, desc, deprecated);
		return;
	}

	if (data_get_type(obj) == DATA_TYPE_NULL)
		data_set_dict(obj);

	xassert(data_get_type(obj) == DATA_TYPE_DICT);

	str = _get_parser_path(parser);
	data_set_string_own(data_key_set(obj, "$ref"), str);

	if (desc) {
		xassert(!data_key_get(obj, "description"));
		data_set_string_own(data_key_set(obj, "description"), desc);
	}

	if (deprecated)
		data_set_bool(data_key_set(obj, "deprecated"), true);

	/* Add schema for $ref target */

	key = _get_parser_key(parser);
	obj = data_key_set(sargs->schemas, key);

	if (data_get_type(obj) == DATA_TYPE_NULL) {
		debug4("%s: adding schema %s", __func__, key);
		_set_openapi_parse(data_set_dict(obj), parser, sargs, NULL,
				   parser->deprecated);
	} else {
		debug4("%s: skip adding duplicate schema %s", __func__, key);
	}

	xfree(key);
}

static data_t *_resolve_parser_key(const parser_t *parser, data_t *dst)
{
	int rc;
	data_t *path = data_set_list(data_new());
	data_t *pkey;

	/*
	 * key may be multiple dicts combined.
	 * Need to create each dict needed to complete path.
	 */

	if ((rc = openapi_append_rel_path(path, parser->key)))
		fatal("%s: failed to split %s: %s", __func__, parser->key,
		      slurm_strerror(rc));

	while ((pkey = data_list_dequeue(path))) {
		data_t *props, *type;

		if (data_get_type(dst) == DATA_TYPE_NULL)
			data_set_dict(dst);

		xassert(data_get_type(pkey) == DATA_TYPE_STRING);
		xassert(data_get_type(dst) == DATA_TYPE_DICT);

		if (!(type = data_key_get(dst, "type")))
			data_set_string(data_key_set(dst, "type"), "object");
		else
			xassert(!xstrcmp(data_get_string(
				data_key_get(dst, "type")), "object"));

		props = data_key_set(dst, "properties");

		xassert((data_get_type(props) == DATA_TYPE_DICT) ||
			(data_get_type(props) == DATA_TYPE_NULL));

		if (data_get_type(props) != DATA_TYPE_DICT)
			data_set_dict(props);

		dst = data_key_set(props, data_get_string(pkey));

		if (data_get_type(dst) == DATA_TYPE_NULL)
			data_set_dict(dst);

		xassert(data_get_type(dst) == DATA_TYPE_DICT);

		FREE_NULL_DATA(pkey);
	}

	FREE_NULL_DATA(path);
	return dst;
}

static data_for_each_cmd_t _convert_list_entry(data_t *data, void *arg)
{
	spec_args_t *sargs = arg;

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);

	if ((data_get_type(data) == DATA_TYPE_LIST) ||
	    (data_get_type(data) == DATA_TYPE_DICT))
		_replace_refs(data, sargs);

	return DATA_FOR_EACH_CONT;
}

static data_for_each_cmd_t _convert_dict_entry(const char *key, data_t *data,
					       void *arg)
{
	spec_args_t *sargs = arg;

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);

	if ((data_get_type(data) == DATA_TYPE_LIST) ||
	    (data_get_type(data) == DATA_TYPE_DICT))
		_replace_refs(data, sargs);

	return DATA_FOR_EACH_CONT;
}

/*
 * Find every $ref = DATA_PARSER_* and add correct path
 */
static void _replace_refs(data_t *data, spec_args_t *sargs)
{
	data_t *ref;

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);
	xassert(sargs->parsers);
	xassert(sargs->parser_count > 0);

	if (!data)
		return;

	if (data_get_type(data) == DATA_TYPE_LIST)
		(void) data_list_for_each(data, _convert_list_entry, sargs);

	if (data_get_type(data) != DATA_TYPE_DICT)
		return;

	if ((ref = data_key_get(data, "$ref")) &&
	     (data_get_type(ref) == DATA_TYPE_STRING) &&
	     !xstrncmp(data_get_string(ref), TYPE_PREFIX,
		       strlen(TYPE_PREFIX))) {
		const parser_t *parser = NULL;

		for (int i = 0; i < sargs->parser_count; i++) {
			if (!xstrcmp(sargs->parsers[i].type_string,
				     data_get_string(ref))) {
				parser = &sargs->parsers[i];
				break;
			}
		}

		if (!parser) {
			debug("%s: skipping unknown %s",
			      __func__, data_get_string(data));
			data_set_null(data);
			return;
		}

		_set_ref(data, NULL, parser, sargs);
	} else {
		(void) data_dict_for_each(data, _convert_dict_entry, sargs);
	}
}

static data_for_each_cmd_t _count_list_entry(data_t *data, void *arg)
{
	spec_args_t *sargs = arg;

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);

	if ((data_get_type(data) == DATA_TYPE_LIST) ||
	    (data_get_type(data) == DATA_TYPE_DICT))
		_count_refs(data, sargs);

	return DATA_FOR_EACH_CONT;
}

static void _increment_ref(const parser_t *parent, const parser_t *parser,
			   spec_args_t *sargs)
{
	uint32_t parser_index;

	parser = unalias_parser(parser);

	if ((parser_index = _resolve_parser_index(parser, sargs)) != NO_VAL) {
		sargs->references[parser_index]++;

		debug4("%s: %s->%s incremented references=%u",
		       __func__, (parent ? parent->type_string : "*" ),
		       parser->type_string, sargs->references[parser_index]);
	}
}

static data_for_each_cmd_t _count_dict_entry(const char *key, data_t *data,
					     void *arg)
{
	spec_args_t *sargs = arg;

	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);

	if (!xstrcmp(key, "$ref") &&
	    (data_get_type(data) == DATA_TYPE_STRING) &&
	    !xstrncmp(data_get_string(data), TYPE_PREFIX,
		      strlen(TYPE_PREFIX)))
		_increment_ref(NULL, _resolve_parser(data_get_string(data),
						     sargs), sargs);

	if ((data_get_type(data) == DATA_TYPE_LIST) ||
	    (data_get_type(data) == DATA_TYPE_DICT))
		_count_refs(data, sargs);

	return DATA_FOR_EACH_CONT;
}

/*
 * Find every $ref = DATA_PARSER_* and count references
 */
static void _count_refs(data_t *data, spec_args_t *sargs)
{
	xassert(sargs->magic == MAGIC_SPEC_ARGS);
	xassert(sargs->args->magic == MAGIC_ARGS);
	xassert(sargs->parsers);
	xassert(sargs->parser_count > 0);

	if (!data)
		return;

	if (data_get_type(data) == DATA_TYPE_DICT)
		(void) data_dict_for_each(data, _count_dict_entry, sargs);
	else if (data_get_type(data) == DATA_TYPE_LIST)
		(void) data_list_for_each(data, _count_list_entry, sargs);
}

static data_t *_add_param(data_t *param, const char *name,
			  openapi_type_format_t format, bool allow_empty,
			  const char *desc, bool deprecated, bool required,
			  spec_args_t *args)
{
	data_t *schema;
	bool in_path = data_key_get(args->path_params, name);

	xassert(format > OPENAPI_FORMAT_INVALID);
	xassert(format < OPENAPI_FORMAT_MAX);

	data_set_string(data_key_set(param, "in"),
			(in_path ? "path" : "query"));
	xassert(name);
	data_set_string(data_key_set(param, "name"), name);
	data_set_string(data_key_set(param, "style"),
			(in_path ? "simple" : "form"));
	data_set_bool(data_key_set(param, "explode"), false);
	if (deprecated)
		data_set_bool(data_key_set(param, "deprecated"), true);
	data_set_bool(data_key_set(param, "allowEmptyValue"), allow_empty);
	data_set_bool(data_key_set(param, "allowReserved"), false);
	if (desc)
		data_set_string(data_key_set(param, "description"), desc);
	data_set_bool(data_key_set(param, "required"), (in_path || required));

	schema = data_set_dict(data_key_set(param, "schema"));
	data_set_string(data_key_set(schema, "type"), "string");

	return schema;
}

static void _add_param_eflags(data_t *params, const parser_t *parser,
			      spec_args_t *args)
{
	parser = find_parser_by_type(parser->type);

	for (int i = 0; i < parser->flag_bit_array_count; i++) {
		const flag_bit_t *bit = &parser->flag_bit_array[i];

		if (!bit->hidden)
			_add_param(data_set_dict(data_list_append(params)),
				   bit->name, OPENAPI_FORMAT_BOOL, true,
				   bit->description,
				   IS_FLAG_BIT_DEPRECATED(bit, args),
				   false, args);
	}
}

static void _add_param_linked(data_t *params, const parser_t *fp,
			      spec_args_t *args)
{
	data_t *schema;
	const parser_t *p;

	if (fp->model == PARSER_MODEL_ARRAY_SKIP_FIELD) {
		return;
	} else if (fp->model ==
		   PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) {
		_add_param_eflags(params, fp, args);
		return;
	} else if (fp->model == PARSER_MODEL_ARRAY_LINKED_FIELD) {
		p = find_parser_by_type(fp->type);
	} else {
		p = fp;
	}

	/* resolve out pointer type to first non-pointer */
	p = unalias_parser(p);

	if (p->model == PARSER_MODEL_ARRAY) {
		/* no way to parse an dictionary/object currently */
		return;
	}

	schema = _add_param(data_set_dict(data_list_append(params)), fp->key,
			    OPENAPI_FORMAT_STRING,
			    (p->obj_openapi == OPENAPI_FORMAT_BOOL),
			    fp->obj_desc, IS_PARSER_DEPRECATED(fp, args),
			    fp->required, args);

	if (fp->model == PARSER_MODEL_ARRAY_LINKED_FIELD)
		fp = find_parser_by_type(fp->type);

	if (fp->flag_bit_array)
		_add_param_flag_enum(schema, fp);
}

extern void set_openapi_schema(data_t *dst, const parser_t *parser,
			       args_t *args)
{
	spec_args_t sargs = {
		.magic = MAGIC_SPEC_ARGS,
		.args = args,
		.spec = dst,
		.disable_refs = true,
	};

	xassert(args->magic == MAGIC_ARGS);
	xassert(data_get_type(dst) == DATA_TYPE_NULL);

	data_set_dict(dst);

	get_parsers(&sargs.parsers, &sargs.parser_count);

	(void) _set_openapi_parse(dst, parser, &sargs, NULL, false);
}

extern int data_parser_p_increment_reference(args_t *args,
					     data_parser_type_t type,
					     refs_ptr_t **references_ptr)
{
	spec_args_t sargs = {
		.magic = MAGIC_SPEC_ARGS,
		.args = args,
	};
	refs_ptr_t *refs = *references_ptr;
	const parser_t *parser;

	get_parsers(&sargs.parsers, &sargs.parser_count);

	if (!refs) {
		refs = *references_ptr = xmalloc(sizeof(*refs));
		refs->magic = MAGIC_REFS_PTR;
		refs->references =
			xcalloc(sargs.parser_count, sizeof(*refs->references));
	}

	if (!(parser = find_parser_by_type(type)))
		return ESLURM_DATA_INVALID_PARSER;

	xassert(refs->magic == MAGIC_REFS_PTR);
	xassert(args->magic == MAGIC_ARGS);
	xassert(type > DATA_PARSER_TYPE_INVALID);
	xassert(type < DATA_PARSER_TYPE_MAX);
	xassert(sargs.parser_count > 0);

	sargs.references = refs->references,
	_increment_ref(NULL, parser, &sargs);

	return SLURM_SUCCESS;
}

extern int data_parser_p_populate_schema(args_t *args, data_parser_type_t type,
					 refs_ptr_t **references_ptr,
					 data_t *dst, data_t *schemas)
{
#ifndef NDEBUG
	refs_ptr_t *refs = *references_ptr;
#endif
	spec_args_t sargs = {
		.magic = MAGIC_SPEC_ARGS,
		.args = args,
		.schemas = schemas,
		.references = (*references_ptr)->references,
	};
	const parser_t *parser;

	xassert(refs && refs->magic == MAGIC_REFS_PTR);
	xassert(args->magic == MAGIC_ARGS);
	xassert(type > DATA_PARSER_TYPE_INVALID);
	xassert(type < DATA_PARSER_TYPE_MAX);
	xassert(data_get_type(dst) == DATA_TYPE_DICT);

	get_parsers(&sargs.parsers, &sargs.parser_count);
	if (!(parser = find_parser_by_type(type)))
		return ESLURM_DATA_INVALID_PARSER;

	_set_ref(dst, NULL, parser, &sargs);

	return SLURM_SUCCESS;
}

extern int data_parser_p_populate_parameters(args_t *args,
					     data_parser_type_t parameter_type,
					     data_parser_type_t query_type,
					     refs_ptr_t **references_ptr,
					     data_t *dst, data_t *schemas)
{
#ifndef NDEBUG
	refs_ptr_t *refs = *references_ptr;
#endif
	spec_args_t sargs = {
		.magic = MAGIC_SPEC_ARGS,
		.args = args,
		.schemas = schemas,
		.references = (*references_ptr)->references,
	};
	const parser_t *param_parser = NULL, *query_parser = NULL;

	xassert(refs && refs->magic == MAGIC_REFS_PTR);
	xassert(args->magic == MAGIC_ARGS);
	xassert(!parameter_type || (parameter_type > DATA_PARSER_TYPE_INVALID));
	xassert(!parameter_type || (parameter_type < DATA_PARSER_TYPE_MAX));
	xassert(!query_type || (query_type > DATA_PARSER_TYPE_INVALID));
	xassert(!query_type || (query_type < DATA_PARSER_TYPE_MAX));
	xassert(data_get_type(dst) == DATA_TYPE_NULL);

	data_set_list(dst);

	get_parsers(&sargs.parsers, &sargs.parser_count);

	sargs.path_params = data_set_dict(data_new());

	if (parameter_type &&
	    !(param_parser =
		      unalias_parser(find_parser_by_type(parameter_type))))
		return ESLURM_DATA_INVALID_PARSER;
	if (query_type &&
	    !(query_parser = unalias_parser(find_parser_by_type(query_type))))
		return ESLURM_DATA_INVALID_PARSER;

	if (param_parser) {
		if (param_parser->model != PARSER_MODEL_ARRAY)
			fatal_abort("parameters must be an array parser");

		debug3("%s: adding parameter %s(0x%"PRIxPTR")=%s to %pd",
		       __func__, param_parser->type_string,
		       (uintptr_t) param_parser, param_parser->obj_type_string,
		       dst);

		for (int i = 0; i < param_parser->field_count; i++)
			data_key_set(sargs.path_params,
				     param_parser->fields[i].key);

		for (int i = 0; i < param_parser->field_count; i++)
			_add_param_linked(dst, &param_parser->fields[i],
					  &sargs);
	}
	if (query_parser) {
		if (query_parser->model != PARSER_MODEL_ARRAY)
			fatal_abort("parameters must be an array parser");

		debug3("%s: adding parameter %s(0x%"PRIxPTR")=%s to %pd",
		       __func__, query_parser->type_string,
		       (uintptr_t) query_parser, query_parser->obj_type_string,
		       dst);

		for (int i = 0; i < query_parser->field_count; i++)
			_add_param_linked(dst, &query_parser->fields[i],
					  &sargs);
	}

	FREE_NULL_DATA(sargs.path_params);

	return SLURM_SUCCESS;
}

extern void data_parser_p_release_references(args_t *args,
					     refs_ptr_t **references_ptr)
{
	refs_ptr_t *refs = *references_ptr;

	xassert(args->magic == MAGIC_ARGS);

	if (!refs)
		return;

	*references_ptr = NULL;

	xassert(refs->magic == MAGIC_REFS_PTR);
	xfree(refs->references);
	refs->magic = ~MAGIC_REFS_PTR;
	xfree(refs);
}
