/*****************************************************************************\
 *  openapi.c - OpenAPI plugin handler
 *****************************************************************************
 *  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/plugrack.h"
#include "src/common/read_config.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "src/interfaces/serializer.h"
#include "src/slurmrestd/openapi.h"
#include "src/slurmrestd/operations.h"

#define OPENAPI_MAJOR_TYPE "openapi"

typedef struct {
	int (*init)(void);
	int (*fini)(void);
	int (*get_paths)(const openapi_path_binding_t **paths_ptr,
			 const openapi_resp_meta_t **meta_ptr);
} funcs_t;

/*
 * Must be synchronized with funcs_t above.
 */
static const char *syms[] = {
	"slurm_openapi_p_init",
	"slurm_openapi_p_fini",
	"slurm_openapi_p_get_paths",
};

typedef enum {
	OPENAPI_PATH_ENTRY_UNKNOWN = 0,
	OPENAPI_PATH_ENTRY_MATCH_STRING,
	OPENAPI_PATH_ENTRY_MATCH_PARAMETER,
	OPENAPI_PATH_ENTRY_MAX
} entry_type_t;

/*
 * This is a simplified entry since OAS allows combos of
 * parameters but we will only honor having a single parameter
 * as an dir entry for now
 */
typedef struct {
	char *entry;
	char *name;
	entry_type_t type;
	openapi_type_t parameter;
} entry_t;

typedef struct {
	const openapi_path_binding_method_t *bound;
	entry_t *entries;
	http_request_method_t method;
} entry_method_t;

#define MAGIC_PATH 0x0a0b09fd
typedef struct {
	int magic; /* MAGIC_PATH */
	char *path; /* path as string */
	const openapi_path_binding_t *bound;
	data_parser_t *parser;
	entry_method_t *methods;
	int tag;
} path_t;

typedef struct {
	const data_t *dpath;
	path_t *path;
	data_t *params;
	http_request_method_t method;
	entry_t *entry;
	int tag;
} match_path_from_data_t;

#define MAGIC_MERGE_PATH 0x22b2ae44
typedef struct {
	int magic; /* MAGIC_MERGE_PATH */
	data_t *paths;
	data_t *server_path;
} merge_path_t;

#define MAGIC_MERGE_ID_PATH 0x22b2aeae
typedef struct {
	int magic; /* MAGIC_MERGE_ID_PATH */
	data_t *server_path;
	char *operation;
	char *at;
	char *path;
	merge_path_t *merge_args;
} id_merge_path_t;

#define MAGIC_OAS 0x1218eeee
typedef struct {
	int magic; /* MAGIC_OAS */
	const char **mime_types;
	data_t *spec;
	data_t *tags;
	data_t *paths;
	data_t *components;
	data_t *components_schemas;
	data_t *security_schemas;
	data_t *info;
	data_t *contact;
	data_t *license;
	data_t *servers;
	data_t *security;
	data_t *x_slurm;
	/* tracked references per data_parser */
	void **references;
} openapi_spec_t;

static list_t *paths = NULL;
static int path_tag_counter = 0;
static plugins_t *plugins = NULL;
static data_parser_t **parsers = NULL; /* symlink to parser array */

static const struct {
	char *openapi_version;
	struct {
		char *title;
		char *desc;
		char *tos;
		struct {
			char *name;
			char *url;
			char *email;
		} contact;
		struct {
			char *name;
			char *url;
		} license;
	} info;
	struct {
		char *name;
		char *desc;
	} tags[3];
	struct {
		char *url;
	} servers[1];
	/* security is too complex for here */
	struct {
		struct security_scheme_s {
			char *key;
			char *type;
			char *desc;
			char *name;
			char *in;
			char *scheme;
			char *bearer_format;
		} security_schemes[3];
	} components;
} openapi_spec = {
	.openapi_version = "3.0.3",
	.info = {
		.title = "Slurm REST API",
		.desc = "API to access and control Slurm",
		.tos = "https://github.com/SchedMD/slurm/blob/master/DISCLAIMER",
		.contact = {
			.name = "SchedMD LLC",
			.url = "https://www.schedmd.com/",
			.email = "sales@schedmd.com",
		},
		.license = {
			.name = "Apache 2.0",
			.url = "https://www.apache.org/licenses/LICENSE-2.0.html",
		},
	},
	.tags = {
		{
			.name = "slurm",
			.desc = "methods that query slurmctld",
		},
		{
			.name = "slurmdb",
			.desc = "methods that query slurmdbd",
		},
		{
			.name = "openapi",
			.desc = "methods that query for generated OpenAPI specifications",
		},
	},
	.servers = {
		{
			.url = "/",
		},
	},
	.components = {
		.security_schemes = {
			{
#define SEC_SCHEME_USER_INDEX 0
				.key = "user",
				.type = "apiKey",
				.desc = "User name",
				.name = "X-SLURM-USER-NAME",
				.in = "header",
			},
			{
#define SEC_SCHEME_TOKEN_INDEX 1
				.key = "token",
				.type = "apiKey",
				.desc = "User access token",
				.name = "X-SLURM-USER-TOKEN",
				.in = "header",
			},
			{
#define SEC_SCHEME_BEARER_INDEX 2
				.key = "bearerAuth",
				.type = "http",
				.desc = "Bearer Authentication",
				.scheme = "bearer",
				.bearer_format = "JWT",
			},
		},
	},
};

static const openapi_path_binding_method_t openapi_methods[] = {
	{
		.method = HTTP_REQUEST_GET,
		.tags = (const char*[]) { "openapi", NULL },
		.summary = "Retrieve OpenAPI Specification",
		.response = {
			.type = DATA_PARSER_OPENAPI_SHARES_RESP,
			.description = "OpenAPI Specification",
		},
		.parameters = DATA_PARSER_SHARES_REQ_MSG,
	},
	{0}
};

static int _op_handler_openapi(openapi_ctxt_t *ctxt);

#define OP_FLAGS (OP_BIND_HIDDEN_OAS | OP_BIND_NO_SLURMDBD)

/*
 * Paths to generate OpenAPI specification
 */
static const openapi_path_binding_t openapi_paths[] = {
	{
		.path = "/openapi.json",
		.callback = _op_handler_openapi,
		.methods = openapi_methods,
		.flags = OP_FLAGS,
	},
	{
		.path = "/openapi.yaml",
		.callback = _op_handler_openapi,
		.methods = openapi_methods,
		.flags = OP_FLAGS,
	},
	{
		.path = "/openapi",
		.callback = _op_handler_openapi,
		.methods = openapi_methods,
		.flags = OP_FLAGS,
	},
	{
		.path = "/openapi/v3",
		.callback = _op_handler_openapi,
		.methods = openapi_methods,
		.flags = OP_FLAGS,
	},
	{0}
};

static const http_status_code_t *response_status_codes = NULL;
/*
 * Default to "default" and 200 as openapi generator breaks with only "default"
 * response code.
 */
static const http_status_code_t default_response_status_codes[] = {
	HTTP_STATUS_CODE_SUCCESS_OK,
	HTTP_STATUS_CODE_DEFAULT,
	HTTP_STATUS_NONE
};

static char *_entry_to_string(entry_t *entry);

static const char *_get_entry_type_string(entry_type_t type)
{
	switch (type) {
	case OPENAPI_PATH_ENTRY_MATCH_STRING:
		return "string";
	case OPENAPI_PATH_ENTRY_MATCH_PARAMETER:
		return "parameter";
	default:
		return "invalid";
	}
}

static int _resolve_parser_index(data_parser_t *parser)
{
	for (int i = 0; parsers[i]; i++)
		if (parsers[i] == parser)
			return i;

	fatal_abort("Unable to find parser. This should never happen!");
}

static void _free_entry_list(entry_t *entry, int tag,
			     entry_method_t *method)
{
	entry_t *itr = entry;

	if (!entry)
		return;

	while (itr->type) {
		debug5("%s: remove path tag:%d method:%s entry:%s name:%s",
		       __func__, tag,
		       (method ? get_http_method_string(method->method) :
				       "N/A"),
		       itr->entry, itr->name);
		xfree(itr->entry);
		xfree(itr->name);
		itr++;
	}

	xfree(entry);
}

static void _list_delete_path_t(void *x)
{
	entry_method_t *em;

	if (!x)
		return;

	path_t *path = x;
	xassert(path->magic == MAGIC_PATH);
	xassert(path->tag != -1);
	em = path->methods;

	while (em->entries) {
		debug5("%s: remove path tag:%d method:%s", __func__, path->tag,
		       get_http_method_string(em->method));

		_free_entry_list(em->entries, path->tag, em);
		em->entries = NULL;
		em++;
	}

	xfree(path->methods);
	xfree(path->path);
	path->magic = ~MAGIC_PATH;
	xfree(path);
}

static entry_t *_parse_openapi_path(const char *str_path, int *count_ptr)
{
	char *save_ptr = NULL;
	char *buffer = xstrdup(str_path);
	char *token = strtok_r(buffer, "/", &save_ptr);
	entry_t *entries = NULL;
	entry_t *entry = NULL;
	int count = 0;

	/* find max bound on number of entries */
	for (const char *i = str_path; *i; i++)
		if (*i == '/')
			count++;

	if (count > 1024)
		fatal_abort("%s: url %s is way too long", str_path, __func__);

	entry = entries = xcalloc((count + 1), sizeof(entry_t));

	while (token) {
		const size_t slen = strlen(token);

		/* ignore // entries */
		if (slen <= 0)
			goto again;

		entry->entry = xstrdup(token);

		if (!xstrcmp(token, ".") || !xstrcmp(token, "..")) {
			/*
			 * there should not be a .. or . in a path
			 * definition, it just doesn't make any sense
			 */
			error("%s: invalid %s at entry",
			      __func__, token);
			goto fail;
		} else if (slen > 3 && token[0] == '{' &&
			   token[slen - 1] == '}') {
			entry->type = OPENAPI_PATH_ENTRY_MATCH_PARAMETER;
			entry->name = xstrndup(token + 1, slen - 2);

			debug5("%s: parameter %s at entry %s",
			       __func__, entry->name, token);
		} else { /* not a variable */
			entry->type = OPENAPI_PATH_ENTRY_MATCH_STRING;
			entry->name = NULL;

			debug5("%s: string match entry %s",
			       __func__, token);
		}

		entry++;
		xassert(entry <= entries + count);
again:
		token = strtok_r(NULL, "/", &save_ptr);
	}

	/* last is always NULL */
	xassert(!entry->type);
	xfree(buffer);
	if (count_ptr)
		*count_ptr = count;
	return entries;

fail:
	_free_entry_list(entries, -1, NULL);
	xfree(buffer);
	if (count_ptr)
		*count_ptr = -1;
	return NULL;
}

static int _print_path_tag_methods(void *x, void *arg)
{
	path_t *path = (path_t *) x;
	int *tag = (int *) arg;

	xassert(path->magic == MAGIC_PATH);

	if (path->tag != *tag)
		return 0;

	if (!path->methods->entries)
		debug4("%s: no methods found in path tag %d",
		       __func__, path->tag);

	for (entry_method_t *em = path->methods; em->entries; em++) {
		char *path_str = _entry_to_string(em->entries);

		debug4("%s: path tag %d entry: %s %s",
		       __func__, path->tag, get_http_method_string(em->method),
		       path_str);

		xfree(path_str);
	}

	/*
	 * We found the (unique) tag, so return -1 to exit early. The item's
	 * index returned by list_for_each_ro() will be negative.
	 */
	return -1;
}

extern void print_path_tag_methods(int tag)
{
	if (get_log_level() < LOG_LEVEL_DEBUG4)
		return;

	if (list_for_each_ro(paths, _print_path_tag_methods, &tag) >= 0)
		error("%s: Tag %d not found in paths", __func__, tag);
}

static void _clone_entries(entry_t **dst_ptr, entry_t *src, int count)
{
	entry_t *dst = xcalloc((count + 1), sizeof(*dst));

	xassert(!*dst_ptr);
	xassert(count > 0);

	*dst_ptr = dst;

	for (; src->type; src++, dst++) {
		dst->entry = xstrdup(src->entry);
		dst->name = xstrdup(src->name);
		dst->type = src->type;
		dst->parameter = src->parameter;
	}
}

static void _check_openapi_path_binding(const openapi_path_binding_t *op_path)
{
#ifndef NDEBUG
	xassert(op_path->path);
	xassert(op_path->callback);
	xassert((op_path->flags == OP_BIND_NONE) ||
		((op_path->flags > OP_BIND_NONE) &&
		 (op_path->flags < OP_BIND_INVALID_MAX)));

	for (int i = 0;; i++) {
		const openapi_path_binding_method_t *method =
			&op_path->methods[i];

		if (method->method == HTTP_REQUEST_INVALID)
			break;

		xassert(method->summary && method->summary[0]);
		xassert(method->response.description &&
			method->response.description[0]);
		xassert(method->method > HTTP_REQUEST_INVALID);
		xassert(method->method < HTTP_REQUEST_MAX);
		xassert(method->tags && method->tags[0]);
		xassert(method->response.type > DATA_PARSER_TYPE_INVALID);
		xassert(method->response.type < DATA_PARSER_TYPE_MAX);
		xassert(method->parameters >= DATA_PARSER_TYPE_INVALID);
		xassert(method->parameters < DATA_PARSER_TYPE_MAX);
		xassert(method->query >= DATA_PARSER_TYPE_INVALID);
		xassert(method->query < DATA_PARSER_TYPE_MAX);
		xassert(method->body.type >= DATA_PARSER_TYPE_INVALID);
		xassert(method->body.type < DATA_PARSER_TYPE_MAX);
	}
#endif /* !NDEBUG */
}

static bool _data_parser_supports_type(data_parser_t *parser,
				       data_parser_type_t type)
{
	openapi_type_t oapi_type;

	oapi_type = data_parser_g_resolve_openapi_type(parser, type, NULL);
	xassert(oapi_type >= OPENAPI_TYPE_INVALID);
	xassert(oapi_type < OPENAPI_TYPE_MAX);

	return (oapi_type != OPENAPI_TYPE_INVALID);
}

static bool _data_parser_supports_method(data_parser_t *parser,
					 const openapi_path_binding_method_t *m)
{
	/* check that parser supports each possible type if set */

	if ((m->response.type != DATA_PARSER_TYPE_INVALID) &&
	    !_data_parser_supports_type(parser, m->response.type))
		return false;

	if ((m->parameters != DATA_PARSER_TYPE_INVALID) &&
	    !_data_parser_supports_type(parser, m->parameters))
		return false;

	if ((m->query != DATA_PARSER_TYPE_INVALID) &&
	    !_data_parser_supports_type(parser, m->query))
		return false;

	if ((m->body.type != DATA_PARSER_TYPE_INVALID) &&
	    !_data_parser_supports_type(parser, m->body.type))
		return false;

	return true;
}

extern int register_path_binding(const char *in_path,
				 const openapi_path_binding_t *op_path,
				 const openapi_resp_meta_t *meta,
				 data_parser_t *parser, int *tag_ptr)
{
	entry_t *entries = NULL;
	int tag = -1, methods_count = 0, entries_count = 0;
	path_t *p = NULL;
	const char *path = (in_path ? in_path : op_path->path);

	debug4("%s: attempting to bind %s with %s",
	       __func__, (parser ? data_parser_get_plugin_version(parser) :
			  "data_parser/none"), path);

	xassert(!!in_path == !!(op_path->flags & OP_BIND_DATA_PARSER));
	_check_openapi_path_binding(op_path);

	if (!(entries = _parse_openapi_path(path, &entries_count)))
		fatal("%s: parse_openapi_path(%s) failed", __func__, path);

	for (int i = 0; op_path->methods[i].method != HTTP_REQUEST_INVALID;
	     i++) {
		if (!_data_parser_supports_method(parser, &op_path->methods[i]))
			continue;

		methods_count++;
	}

	if (!methods_count) {
		debug5("%s: skip binding %s with %s",
		       __func__, path, data_parser_get_plugin(parser));
		_free_entry_list(entries, -1, NULL);
		return ESLURM_NOT_SUPPORTED;
	}

	tag = path_tag_counter++;

	p = xmalloc(sizeof(*p));
	p->magic = MAGIC_PATH;
	p->methods = xcalloc((methods_count + 1), sizeof(*p->methods));
	p->tag = tag;
	p->bound = op_path;
	p->parser = parser;
	p->path = xstrdup(path);

	for (int i = 0, mi = 0;; i++) {
		const openapi_path_binding_method_t *m = &op_path->methods[i];
		entry_method_t *t = &p->methods[mi];
		entry_t *e;

		if (m->method == HTTP_REQUEST_INVALID)
			break;

		/*
		 * Skip method if data_parser does not support any of the in/out
		 * types which would just cause slurmrestd to abort() later.
		 */
		if (!_data_parser_supports_method(parser, m)) {
			debug5("%s: skip binding \"%s %s\" with %s",
			       __func__, get_http_method_string(m->method),
			       path, data_parser_get_plugin(parser));
			continue;
		}

		t->method = m->method;
		t->bound = m;

		if (i != 0) {
			_clone_entries(&t->entries, entries, entries_count);
			e = t->entries;
		} else {
			p->methods[0].entries = e = entries;
		}

		for (; e->type; e++) {
			if (e->type == OPENAPI_PATH_ENTRY_MATCH_PARAMETER)
				e->parameter =
					data_parser_g_resolve_openapi_type(
						parser, m->parameters, e->name);

			debug5("%s: add binded path %s entry: method=%s tag=%d entry=%s name=%s parameter=%s entry_type=%s",
			       __func__, path,
			       get_http_method_string(m->method), tag, e->entry,
			       e->name, openapi_type_to_string(e->parameter),
			       _get_entry_type_string(e->type));
		}

		/* only move to next method if populated */
		mi++;
	}

	list_append(paths, p);
	*tag_ptr = tag;
	return SLURM_SUCCESS;
}

/*
 * Check if the entry matches based on the OAS type
 * and if it does, then add that matched parameter
 */
static bool _match_param(const data_t *data, match_path_from_data_t *args)
{
	bool matched = false;
	entry_t *entry = args->entry;
	data_t *params = args->params;
	data_t *match = data_new();

	data_copy(match, data);

	switch (entry->parameter) {
	case OPENAPI_TYPE_NUMBER:
	{
		if (data_convert_type(match, DATA_TYPE_FLOAT) ==
		    DATA_TYPE_FLOAT) {
			data_set_float(data_key_set(params, entry->name),
				       data_get_float(match));
			matched = true;
		}
		break;
	}
	case OPENAPI_TYPE_INTEGER:
	{
		if (data_convert_type(match, DATA_TYPE_INT_64) ==
		    DATA_TYPE_INT_64) {
			data_set_int(data_key_set(params, entry->name),
				     data_get_int(match));
			matched = true;
		}
		break;
	}
	default: /* assume string */
		debug("%s: unknown parameter type %s",
		      __func__, openapi_type_to_string(entry->parameter));
		/* fall through */
	case OPENAPI_TYPE_STRING:
	{
		if (data_convert_type(match, DATA_TYPE_STRING) ==
		    DATA_TYPE_STRING) {
			data_set_string(data_key_set(params, entry->name),
					data_get_string(match));
			matched = true;
		}
		break;
	}
	}

	if (get_log_level() >= LOG_LEVEL_DEBUG5) {
		char *str = NULL;
		data_get_string_converted(data, &str);

		debug5("%s: parameter %s[%s]->%s[%s] result=%s",
		       __func__, entry->name,
		       openapi_type_to_string(entry->parameter),
		       str, data_get_type_string(data),
		       (matched ? "matched" : "failed"));

		xfree(str);
	}

	FREE_NULL_DATA(match);
	return matched;
}

static data_for_each_cmd_t _match_path(const data_t *data, void *y)
{
	match_path_from_data_t *args = y;
	entry_t *entry = args->entry;

	if (!entry->type)
		return DATA_FOR_EACH_FAIL;

	if (entry->type == OPENAPI_PATH_ENTRY_MATCH_STRING) {
		bool match;

		if (data_get_type(data) != DATA_TYPE_STRING)
			return DATA_FOR_EACH_FAIL;

		match = !xstrcmp(data_get_string(data), entry->entry);

		debug5("%s: string attempt match %s to %s: %s",
		       __func__, entry->entry, data_get_string(data),
		       (match ? "SUCCESS" : "FAILURE"));

		if (!match)
			return DATA_FOR_EACH_FAIL;
	} else if (entry->type == OPENAPI_PATH_ENTRY_MATCH_PARAMETER) {
		if (!_match_param(data, args))
			return DATA_FOR_EACH_FAIL;
	} else
		fatal_abort("%s: unknown OAS path entry match type",
			    __func__);

	args->entry++;
	return DATA_FOR_EACH_CONT;
}

static char *_entry_to_string(entry_t *entry)
{
	char *path = NULL;
	data_t *d = data_set_list(data_new());

	for (; entry->type; entry++) {
		switch (entry->type) {
		case OPENAPI_PATH_ENTRY_MATCH_STRING:
			data_set_string(data_list_append(d), entry->entry);
			break;
		case OPENAPI_PATH_ENTRY_MATCH_PARAMETER:
			data_set_string_fmt(data_list_append(d), "{%s}",
					    entry->name);
			break;
		case OPENAPI_PATH_ENTRY_UNKNOWN:
		case OPENAPI_PATH_ENTRY_MAX:
			fatal_abort("invalid entry type");
		}
	}

	serialize_g_data_to_string(&path, NULL, d, MIME_TYPE_JSON,
				   SER_FLAGS_COMPACT);

	FREE_NULL_DATA(d);
	return path;
}

static int _match_path_from_data(void *x, void *key)
{
	char *dst_path = NULL, *src_path = NULL;
	match_path_from_data_t *args = key;
	path_t *path = x;
	entry_method_t *method;
	bool matched = false;

	xassert(path->magic == MAGIC_PATH);

	if (get_log_level() >= LOG_LEVEL_DEBUG5) {
		serialize_g_data_to_string(&dst_path, NULL, args->dpath,
					   MIME_TYPE_JSON, SER_FLAGS_COMPACT);
	}

	args->path = path;
	for (method = path->methods; method->entries; method++) {
		int entries = 0;

		if (get_log_level() >= LOG_LEVEL_DEBUG5) {
			xfree(src_path);
			src_path = _entry_to_string(method->entries);
		}

		if (args->method != method->method) {
			debug5("%s: method skip for %s(%d, %s != %s) to %s(0x%"PRIXPTR")",
			       __func__, src_path, args->path->tag,
			       get_http_method_string(args->method),
			       get_http_method_string(method->method),
			       dst_path, (uintptr_t) args->dpath);
			continue;
		}

		for (args->entry = method->entries; args->entry->type;
		     entries++, args->entry++)
			/* do nothing */;

		if (data_get_list_length(args->dpath) != entries) {
			debug5("%s: skip non-matching subdirectories: registered=%u requested=%zu ",
			       __func__, entries,
			       data_get_list_length(args->dpath));
			continue;
		}

		args->entry = method->entries;
		if (data_list_for_each_const(args->dpath, _match_path,
					     args) < 0) {
			debug5("%s: match failed %s",
			       __func__, args->entry->entry);
			continue;
		}

		/*
		 * The list is NULL terminated, so if entry->type is not NULL
		 * we didn't match the whole list, but we already don't have
		 * anything to compare in request.
		 */
		if (!args->entry->type) {
			args->tag = path->tag;
			matched = true;
			break;
		}
	}

	debug5("%s: match %s for %s(%d, %s) to %s(0x%"PRIXPTR")",
	       __func__,
	       matched ? "successful" : "failed",
	       src_path,
	       args->path->tag,
	       get_http_method_string(args->method),
	       dst_path,
	       (uintptr_t) args->dpath);

	xfree(src_path);
	xfree(dst_path);

	return matched;
}

extern int find_path_tag(const data_t *dpath, data_t *params,
			 http_request_method_t method)
{
	match_path_from_data_t args = {
		.params = params,
		.dpath = dpath,
		.method = method,
		.tag = -1,
	};

	xassert(data_get_type(params) == DATA_TYPE_DICT);

	(void) list_find_first(paths, _match_path_from_data, &args);

	return args.tag;
}

static int _bind_paths(const openapi_path_binding_t *paths,
		       const openapi_resp_meta_t *meta)
{
	int rc = SLURM_SUCCESS;

	for (int i = 0; paths[i].path; i++) {
		const openapi_path_binding_t *op_path = &paths[i];

		if ((rc = bind_operation_path(op_path, meta)))
			break;
	}

	return rc;
}

extern int init_openapi(const char *plugin_list, plugrack_foreach_t listf,
			data_parser_t **parsers_ptr,
			const http_status_code_t *resp_status_codes)
{
	int rc;

	if (paths)
		fatal("%s called twice", __func__);

	if (resp_status_codes)
		response_status_codes = resp_status_codes;
	else
		response_status_codes = default_response_status_codes;

	paths = list_create(_list_delete_path_t);

	/* must have JSON plugin to parse the openapi.json */
	serializer_required(MIME_TYPE_JSON);

	if ((rc = _bind_paths(openapi_paths, NULL)))
		fatal("Unable to bind openapi specification paths: %s",
		      slurm_strerror(rc));

	rc = load_plugins(&plugins, OPENAPI_MAJOR_TYPE, plugin_list, listf,
			  syms, ARRAY_SIZE(syms));

	if (!xstrcasecmp("list", plugin_list))
		return SLURM_SUCCESS;

	if (rc)
		fatal("Loading OpenAPI plugins failed: %s", slurm_strerror(rc));

	if ((rc = load_plugins(&plugins, OPENAPI_MAJOR_TYPE, plugin_list, listf,
			       syms, ARRAY_SIZE(syms))))
		fatal("Loading OpenAPI plugins failed: %s", slurm_strerror(rc));

	if (!plugins->count)
		fatal("No OpenAPI plugins loaded.");

	parsers = parsers_ptr;

	for (size_t i = 0; i < plugins->count; i++) {
		const funcs_t *funcs = plugins->functions[i];
		const openapi_path_binding_t *paths;
		const openapi_resp_meta_t *meta;

		if ((rc = funcs->get_paths(&paths, &meta)))
			fatal("Failure loading plugin path bindings: %s",
			      slurm_strerror(rc));

		if ((rc = _bind_paths(paths, meta)))
			fatal("Unable to bind openapi specification paths: %s",
			      slurm_strerror(rc));
	}

	/* Call init() after all plugins are fully loaded */
	for (size_t i = 0; i < plugins->count; i++) {
		const funcs_t *funcs = plugins->functions[i];
		funcs->init();
	}

	return rc;
}

extern void destroy_openapi(void)
{
	if (!paths)
		return;

	for (size_t i = 0; i < plugins->count; i++) {
		const funcs_t *funcs = plugins->functions[i];
		funcs->fini();
	}

	FREE_NULL_PLUGINS(plugins);
	FREE_NULL_LIST(paths);
}

static data_for_each_cmd_t _merge_operationId_strings(data_t *data, void *arg)
{
	id_merge_path_t *args = arg;
	char *p;

	xassert(args->magic == MAGIC_MERGE_ID_PATH);
	xassert(args->merge_args->magic == MAGIC_MERGE_PATH);

	if (data_convert_type(data, DATA_TYPE_STRING) != DATA_TYPE_STRING)
		return DATA_FOR_EACH_FAIL;

	p = xstrdup(data_get_string(data));

	/* sub out '.' for '_' to avoid breaking compilers */
	for (int s = strlen(p), i = 0; i < s; i++)
		if ((p[i] == '.') || (p[i] == '{') || (p[i] == '}'))
			p[i] = '_';

	xstrfmtcatat(args->operation, &args->at, "%s%s",
		     (args->operation ? "_" : ""), data_get_string(data));

	xfree(p);

	return DATA_FOR_EACH_CONT;
}

static data_for_each_cmd_t _foreach_strip_params(data_t *data, void *arg)
{
	const char *item = data_get_string(data);
	data_t **last_ptr = arg;
	int len = strlen(item);

	xassert(item);
	if (!item || (item[0] != '{')) {
		char *dst = xstrdup(item);
		char *last = dst;

		/* strip out '.' */
		for (int i = 0; i < len; i++) {
			if (item[i] == '.')
				continue;

			*last = item[i];
			last++;
		}

		*last = '\0';

		data_set_string_own(data, dst);

		*last_ptr = data;
		return DATA_FOR_EACH_CONT;
	}

	xassert(len > 2);
	xassert(item[len - 1] == '}');
	if (*last_ptr &&
	    !xstrncmp(data_get_string(*last_ptr), (item + 1), (len - 2))) {
		/*
		 * Last item is the same as the parameter name which means that
		 * the item is uncountable and we need to set last as single.
		 */
		data_set_string(data, data_get_string(*last_ptr));
		data_set_string(*last_ptr, "single");
		return DATA_FOR_EACH_CONT;
	}

	return DATA_FOR_EACH_DELETE;
}

/* Caller must xfree() returned string */
static char *_get_method_operationId(openapi_spec_t *spec, path_t *path,
				     const openapi_path_binding_method_t
					     *method)
{
	data_t *merge[10] = {0}, *dpath, *merged = NULL, *last = NULL;
	const char *method_str = get_http_method_string_lc(method->method);
	int i = 0;
	merge_path_t merge_args = {
		.magic = MAGIC_MERGE_PATH,
		.paths = spec->paths,
	};
	id_merge_path_t merge_id_args = {
		.magic = MAGIC_MERGE_ID_PATH,
		.merge_args = &merge_args,
	};

	dpath = parse_url_path(path->path, false, true);

	xassert((data_get_list_length(dpath) + 1) < (ARRAY_SIZE(merge) - 1));

	(void) data_list_for_each(dpath, _foreach_strip_params, &last);

	if (data_get_list_length(dpath) < 3) {
		/* unversioned paths */
		merge[i++] = data_set_string(data_new(), method_str);
	} else {
		merge[i++] = data_list_dequeue(dpath); /* slurm vs slurmdb */
		merge[i++] = data_list_dequeue(dpath); /* v0.0.XX */
		merge[i++] = data_set_string(data_new(), method_str);
	}

	while (data_get_list_length(dpath) && (i < (ARRAY_SIZE(merge) - 1)))
		merge[i++] = data_list_dequeue(dpath);

	merged = data_list_join((const data_t **) merge, true);
	if (data_list_for_each(merged, _merge_operationId_strings,
			       &merge_id_args) < 0)
		fatal_abort("_merge_operationId_strings() failed which should never happen");

	for (i = 0; i < ARRAY_SIZE(merge); i++)
		FREE_NULL_DATA(merge[i]);
	FREE_NULL_DATA(merged);
	FREE_NULL_DATA(dpath);

	debug5("%s: [%s %s] setting OperationId: %s",
	       __func__, method_str, path->path, merge_id_args.operation);

	return merge_id_args.operation;
}

static int _populate_method(path_t *path, openapi_spec_t *spec, data_t *dpath,
			    const openapi_path_binding_method_t *method)
{
	const char **mime_types = spec->mime_types;
	void *refs = &spec->references[_resolve_parser_index(path->parser)];
	data_t *dmethod = data_set_dict(data_key_set(dpath,
		get_http_method_string_lc(method->method)));
	data_t *dtags = data_set_list(data_key_set(dmethod, "tags"));

	for (int i = 0; method->tags[i]; i++)
		data_set_string(data_list_append(dtags), method->tags[i]);

	if (method->summary)
		data_set_string(data_key_set(dmethod, "summary"),
				method->summary);
	if (method->description)
		data_set_string(data_key_set(dmethod, "description"),
				method->description);

	if (data_parser_g_is_deprecated(path->parser))
		data_set_bool(data_key_set(dmethod, "deprecated"), true);

	{
		char *opid = _get_method_operationId(spec, path, method);
		data_set_string_own(data_key_set(dmethod, "operationId"), opid);
	}

	if (method->parameters || method->query) {
		/*
		 * Use existing replacements
		 */
		data_t *dst = data_key_set(dmethod, "parameters");

		if (data_parser_g_populate_parameters(path->parser,
						      method->parameters,
						      method->query, refs, dst,
						      spec->components_schemas))
			fatal_abort("data_parser_g_populate_parameters() failed");
	}

	if (method->response.type) {
		data_t *dresp = data_set_dict(data_key_set(dmethod, "responses"));
		data_t *resp_code = data_set_dict(data_new());
		data_t *cnt = data_set_dict(data_key_set(resp_code, "content"));

		if (method->response.description)
			data_set_string(data_set_dict(data_key_set(resp_code,
				"description")), method->response.description);

		for (int i = 0; mime_types[i]; i++) {
			data_t *dtype, *dschema;

			/*
			 * Never return URL encoded mimetype as it is only for
			 * HTTP query
			 */
			if (!xstrcmp(mime_types[i], MIME_TYPE_URL_ENCODED))
				continue;

			dtype = data_set_dict(data_key_set(cnt, mime_types[i]));
			dschema = data_set_dict(data_key_set(dtype, "schema"));

			if (data_parser_g_populate_schema(path->parser,
				method->response.type, refs, dschema,
				spec->components_schemas))
				fatal_abort("data_parser_g_populate_schema() failed");
		}

		for (int i = 0; response_status_codes[i]; i++) {
			const http_status_code_t code =
				response_status_codes[i];
			char str[64];

			if (code == HTTP_STATUS_CODE_DEFAULT)
				snprintf(str, sizeof(str), "%s",
					 get_http_status_code_string(code));
			else
				snprintf(str, sizeof(str), "%u", code);

			data_copy(data_key_set(dresp, str), resp_code);
		}

		FREE_NULL_DATA(resp_code);
	}

	if (method->body.type) {
		data_t *dbody = data_set_dict(data_key_set(dmethod,
							   "requestBody"));
		data_t *cnt = data_set_dict(data_key_set(dbody, "content"));

		if (method->body.description)
			data_set_string(data_set_dict(data_key_set(dbody,
				"description")), method->body.description);

		for (int i = 0; mime_types[i]; i++) {
			data_t *dtype, *dschema;

			/*
			 * Never return URL encoded mimetype as it is only for
			 * HTTP query
			 */
			if (!xstrcmp(mime_types[i], MIME_TYPE_URL_ENCODED))
				continue;

			dtype = data_set_dict(data_key_set(cnt, mime_types[i]));
			dschema = data_set_dict(data_key_set(dtype, "schema"));

			if (data_parser_g_populate_schema(path->parser,
				method->body.type, refs, dschema,
				spec->components_schemas))
				fatal_abort("data_parser_g_populate_schema() failed");
		}

	}

	return SLURM_SUCCESS;
}

static int _foreach_add_path(void *x, void *arg)
{
	int rc = SLURM_SUCCESS;
	path_t *path = x;
	openapi_spec_t *spec = arg;
	const openapi_path_binding_t *bound = path->bound;
	data_t *dpath;

	xassert(spec->magic == MAGIC_OAS);
	xassert(path->magic == MAGIC_PATH);

	if (!bound)
		return SLURM_SUCCESS;

	if (bound->flags & OP_BIND_HIDDEN_OAS)
		return SLURM_SUCCESS;

	xassert(!data_key_get(spec->paths, path->path));
	dpath = data_set_dict(data_key_set(spec->paths, path->path));

	for (int i = 0; !rc && path->methods[i].method; i++)
		rc = _populate_method(path, spec, dpath,
				      path->methods[i].bound);

	return rc;
}

static int _foreach_count_path(void *x, void *arg)
{
	path_t *path = x;
	openapi_spec_t *spec = arg;
	const char **mime_types = spec->mime_types;
	const openapi_path_binding_t *bound = path->bound;
	void *refs;

	xassert(spec->magic == MAGIC_OAS);
	xassert(path->magic == MAGIC_PATH);

	if (!bound)
		return SLURM_SUCCESS;

	refs = &spec->references[_resolve_parser_index(path->parser)];

	for (int i = 0; path->methods[i].method; i++) {
		const openapi_path_binding_method_t *method =
			path->methods[i].bound;

		if (method->parameters &&
		    data_parser_g_increment_reference(path->parser,
						      method->parameters, refs))
			fatal_abort("data_parser_g_increment_reference() failed");

		if (method->query &&
		    data_parser_g_increment_reference(path->parser,
						      method->query, refs))
			fatal_abort("data_parser_g_increment_reference() failed");

		if (method->body.type) {
			/*
			 * Need to add 1 reference per mime type that will get
			 * dumped
			 */
			for (int i = 0; mime_types[i]; i++)
				if (data_parser_g_increment_reference(
					path->parser, method->body.type, refs))
					fatal_abort("data_parser_g_increment_reference() failed");
		}

		if (method->response.type) {
			/*
			 * Need to add 1 reference per mime type that will get
			 * dumped
			 */
			for (int i = 0; mime_types[i]; i++)
				if (data_parser_g_increment_reference(
					path->parser, method->response.type,
					refs))
					fatal_abort("data_parser_g_increment_reference() failed");
		}
	}

	return SLURM_SUCCESS;
}

extern int generate_spec(data_t *dst, const char **mime_types)
{
	openapi_spec_t spec = {
		.magic = MAGIC_OAS,
		.spec = dst,
		.mime_types = mime_types,
	};
	data_t *security1, *security2, *security3;
	data_t *openapi_plugins, *data_parsers, *slurm_version;
	char *version = xstrdup_printf("Slurm-%s", SLURM_VERSION_STRING);
	int parsers_count;

	/* count the parsers present to allocate refs counts */
	for (parsers_count = 0; parsers[parsers_count]; parsers_count++);
	spec.references = xcalloc(parsers_count, sizeof(*spec.references));

	data_set_dict(spec.spec);
	spec.tags = data_set_list(data_key_set(spec.spec, "tags"));
	spec.paths = data_set_dict(data_key_set(spec.spec, "paths"));
	spec.components = data_set_dict(data_key_set(spec.spec, "components"));
	spec.components_schemas = data_set_dict(data_key_set(spec.components,
							     "schemas"));
	spec.security_schemas = data_set_dict(data_key_set(spec.components,
							   "securitySchemes"));
	spec.info = data_set_dict(data_key_set(spec.spec, "info"));
	spec.contact = data_set_dict(data_key_set(spec.info, "contact"));
	spec.license = data_set_dict(data_key_set(spec.info, "license"));
	spec.x_slurm = data_set_dict(data_key_set(spec.info, "x-slurm"));
	spec.servers = data_set_list(data_key_set(spec.spec, "servers"));
	spec.security = data_set_list(data_key_set(spec.spec, "security"));
	security1 = data_set_dict(data_list_append(spec.security));
	security2 = data_set_dict(data_list_append(spec.security));
	security3 = data_set_dict(data_list_append(spec.security));
	data_parsers =
		data_set_list(data_key_set(spec.x_slurm, "data_parsers"));
	openapi_plugins = data_set_list(data_key_set(spec.x_slurm, "openapi"));
	slurm_version = data_set_dict(data_key_set(spec.x_slurm, "version"));

	data_set_string(data_key_set(spec.spec, "openapi"),
			openapi_spec.openapi_version);
	data_set_string(data_key_set(spec.info, "title"), openapi_spec.info.title);
	data_set_string(data_key_set(spec.info, "description"),
			openapi_spec.info.desc);
	data_set_string(data_key_set(spec.info, "termsOfService"),
			openapi_spec.info.tos);
	data_set_string_own(data_key_set(spec.info, "version"), version);

	/* Populate info spec extension x-slurm with data_parsers and flags */
	for (int i = 0; i < parsers_count; i++) {
		data_t *tmp_data = data_list_append(data_parsers);

		data_set_dict(tmp_data);
		data_set_string(data_key_set(tmp_data, "plugin"),
				data_parser_get_plugin_version(parsers[i]));
		if (data_parser_g_dump_flags(parsers[i],
					     data_key_set(tmp_data, "flags")))
			fatal_abort("data_parser_g_dump_flags() failed");
	}

	/* Populate info spec extension x-slurm with openapi plugins */
	for (int i = 0; i < plugins->count; i++)
		data_set_string(data_list_append(openapi_plugins),
				plugins->types[i]);

	data_set_string(data_key_set(slurm_version, "major"), SLURM_MAJOR);
	data_set_string(data_key_set(slurm_version, "micro"), SLURM_MICRO);
	data_set_string(data_key_set(slurm_version, "minor"), SLURM_MINOR);
	data_set_string(data_key_set(spec.x_slurm, "release"),
			SLURM_VERSION_STRING);
	data_set_string(data_key_set(spec.contact, "name"),
			openapi_spec.info.contact.name);
	data_set_string(data_key_set(spec.contact, "url"),
			openapi_spec.info.contact.url);
	data_set_string(data_key_set(spec.contact, "email"),
			openapi_spec.info.contact.email);
	data_set_string(data_key_set(spec.license, "name"),
			openapi_spec.info.license.name);
	data_set_string(data_key_set(spec.license, "url"),
			openapi_spec.info.license.url);

	for (int i = 0; i < ARRAY_SIZE(openapi_spec.tags); i++) {
		data_t *tag = data_set_dict(data_list_append(spec.tags));
		data_set_string(data_key_set(tag, "name"),
				openapi_spec.tags[i].name);
		data_set_string(data_key_set(tag, "description"),
				openapi_spec.tags[i].desc);
	}
	for (int i = 0; i < ARRAY_SIZE(openapi_spec.servers); i++) {
		data_t *server = data_set_dict(data_list_append(spec.servers));
		data_set_string(data_key_set(server, "url"),
				openapi_spec.servers[i].url);
	}

	/* Add default of no auth required */
	data_set_dict(data_list_append(spec.security));
	/* Add user and token auth */
	data_set_list(data_key_set(
		security1,
		openapi_spec.components.security_schemes[SEC_SCHEME_USER_INDEX]
			.key));
	data_set_list(data_key_set(
		security1,
		openapi_spec.components.security_schemes[SEC_SCHEME_TOKEN_INDEX]
			.key));
	/* Add only token auth */
	data_set_list(data_key_set(
		security2,
		openapi_spec.components.security_schemes[SEC_SCHEME_TOKEN_INDEX]
			.key));
	/* Add only bearer */
	data_set_list(data_key_set(
		security3, openapi_spec.components
				   .security_schemes[SEC_SCHEME_BEARER_INDEX]
				   .key));

	for (int i = 0;
	     i < ARRAY_SIZE(openapi_spec.components.security_schemes); i++) {
		const struct security_scheme_s *s =
			&openapi_spec.components.security_schemes[i];
		data_t *schema =
			data_set_dict(data_key_set(spec.security_schemas,
						   s->key));
		data_set_string(data_key_set(schema, "type"), s->type);
		data_set_string(data_key_set(schema, "description"), s->desc);

		if (s->name)
			data_set_string(data_key_set(schema, "name"), s->name);
		if (s->in)
			data_set_string(data_key_set(schema, "in"), s->in);
		if (s->scheme)
			data_set_string(data_key_set(schema, "scheme"),
					s->scheme);
		if (s->bearer_format)
			data_set_string(data_key_set(schema, "bearerFormat"),
					s->bearer_format);
	}

	(void) list_for_each(paths, _foreach_count_path, &spec);

	/* Add generated paths */
	(void) list_for_each(paths, _foreach_add_path, &spec);

	for (int i = 0; parsers[i]; i++)
		if (spec.references[i])
			data_parser_g_release_references(parsers[i],
							 &spec.references[i]);
	xfree(spec.references);

	/*
	 * We currently fatal instead of returning failure since openapi are
	 * compile time static and we should not be failing to serve the specs
	 * out
	 */
	return SLURM_SUCCESS;
}

static int _op_handler_openapi(openapi_ctxt_t *ctxt)
{
	return generate_spec(ctxt->resp, get_mime_type_array());
}

static bool _on_error(void *arg, data_parser_type_t type, int error_code,
		      const char *source, const char *why, ...)
{
	va_list ap;
	char *str;
	openapi_ctxt_t *ctxt = arg;

	va_start(ap, why);
	str = vxstrfmt(why, ap);
	va_end(ap);

	openapi_resp_error(ctxt, error_code, source, "%s", str);

	xfree(str);

	return false;
}

static void _on_warn(void *arg, data_parser_type_t type, const char *source,
		     const char *why, ...)
{
	va_list ap;
	char *str;
	openapi_ctxt_t *ctxt = arg;

	va_start(ap, why);
	str = vxstrfmt(why, ap);
	va_end(ap);

	openapi_resp_warn(ctxt, source, "%s", str);

	xfree(str);
}

extern int openapi_resp_error(openapi_ctxt_t *ctxt, int error_code,
			      const char *source, const char *why, ...)
{
	openapi_resp_error_t *e;

	xassert(ctxt->errors);

	if (!ctxt->errors)
		return error_code;

	e = xmalloc(sizeof(*e));

	if (why) {
		va_list ap;
		char *str;

		va_start(ap, why);
		str = vxstrfmt(why, ap);
		va_end(ap);

		error("%s: [%s] parser=%s rc[%d]=%s -> %s",
		      (source ? source : __func__), ctxt->id,
		      data_parser_get_plugin(ctxt->parser), error_code,
		      slurm_strerror(error_code), str);

		e->description = str;
	}

	if (error_code) {
		e->num = error_code;

		if (!ctxt->rc)
			ctxt->rc = error_code;
	}

	if (source)
		e->source = xstrdup(source);

	list_append(ctxt->errors, e);

	return error_code;
}

extern void openapi_resp_warn(openapi_ctxt_t *ctxt, const char *source,
			      const char *why, ...)
{
	openapi_resp_warning_t *w;

	xassert(ctxt->warnings);

	if (!ctxt->warnings)
		return;

	w = xmalloc(sizeof(*w));

	if (why) {
		va_list ap;
		char *str;

		va_start(ap, why);
		str = vxstrfmt(why, ap);
		va_end(ap);

		debug("%s: [%s] parser=%s WARNING: %s",
		      (source ? source : __func__), ctxt->id,
		      data_parser_get_plugin(ctxt->parser), str);

		w->description = str;
	}

	if (source)
		w->source = xstrdup(source);

	list_append(ctxt->warnings, w);
}

static void _populate_openapi_results(openapi_ctxt_t *ctxt,
				      openapi_resp_meta_t *query_meta)
{
	data_t *errors, *warnings, *meta;
	int rc;

	/* need to populate meta, errors and warnings */
	errors = data_key_set(ctxt->resp,
		XSTRINGIFY(OPENAPI_RESP_STRUCT_ERRORS_FIELD_NAME));
	warnings = data_key_set(ctxt->resp,
		XSTRINGIFY(OPENAPI_RESP_STRUCT_WARNINGS_FIELD_NAME));
	meta = data_key_set(ctxt->resp,
		XSTRINGIFY(OPENAPI_RESP_STRUCT_META_FIELD_NAME));

	if (data_get_type(meta) == DATA_TYPE_NULL)
		DATA_DUMP(ctxt->parser, OPENAPI_META_PTR, query_meta, meta);

	if (data_get_type(errors) == DATA_TYPE_LIST) {
		if (!data_get_list_length(errors))
			data_set_null(errors);
		else
			xassert(list_is_empty(ctxt->errors));
	}

	if ((data_get_type(errors) == DATA_TYPE_NULL) &&
	    ((rc = DATA_DUMP(ctxt->parser, OPENAPI_ERRORS, ctxt->errors,
			     errors)))) {
		/* data_parser doesn't support OPENAPI_ERRORS parser */
		data_t *e =
			data_set_dict(data_list_append(data_set_list(errors)));
		data_set_string(data_key_set(e, "description"),
				"Requested data_parser plugin does not support OpenAPI plugin");
		data_set_int(data_key_set(e, "error_number"),
			     ESLURM_NOT_SUPPORTED);
		data_set_string(data_key_set(e, "error"),
				slurm_strerror(ESLURM_NOT_SUPPORTED));
	}

	if (data_get_type(warnings) == DATA_TYPE_LIST) {
		if (!data_get_list_length(warnings))
			data_set_null(warnings);
		else
			xassert(list_is_empty(ctxt->warnings));
	}

	if (data_get_type(warnings) == DATA_TYPE_NULL)
		DATA_DUMP(ctxt->parser, OPENAPI_WARNINGS, ctxt->warnings,
			  warnings);
}

extern int wrap_openapi_ctxt_callback(const char *context_id,
				      http_request_method_t method,
				      data_t *parameters, data_t *query,
				      int tag, data_t *resp, void *auth,
				      data_parser_t *parser,
				      const openapi_path_binding_t *op_path,
				      const openapi_resp_meta_t *plugin_meta)
{
	int rc = SLURM_SUCCESS;
	openapi_ctxt_t ctxt = {
		.id = context_id,
		.method = method,
		.parameters = parameters,
		.query = query,
		.resp = resp,
		.tag = tag,
	};
	openapi_resp_meta_t query_meta = {{0}};
	openapi_ctxt_handler_t callback = op_path->callback;

	if (plugin_meta)
		query_meta = *plugin_meta;

	query_meta.plugin.data_parser = (char *) data_parser_get_plugin(parser);
	query_meta.plugin.accounting_storage =
		(char *) slurm_conf.accounting_storage_type;
	query_meta.client.source = (char *) context_id;
	query_meta.slurm.cluster = slurm_conf.cluster_name;

	ctxt.parent_path = data_set_list(data_new());
	ctxt.errors = list_create(free_openapi_resp_error);
	ctxt.warnings = list_create(free_openapi_resp_warning);
	ctxt.parser = data_parser_g_new(_on_error, _on_error, _on_error, &ctxt,
					_on_warn, _on_warn, _on_warn, &ctxt,
					data_parser_get_plugin(parser), NULL,
					true);

	debug("%s: [%s] %s using %s",
	      __func__, context_id, get_http_method_string(method),
	      data_parser_get_plugin(ctxt.parser));

	if (op_path->flags & OP_BIND_NO_SLURMDBD) {
		; /* Do not attempt to open a connection to slurmdbd */
	} else if (slurm_conf.accounting_storage_type &&
		   !(ctxt.db_conn = openapi_get_db_conn(auth))) {
		char *auth_error_msg = "";
		if (errno == SLURM_PROTOCOL_AUTHENTICATION_ERROR)
			auth_error_msg = ", authentication error";
		if (op_path->flags & OP_BIND_REQUIRE_SLURMDBD)
			openapi_resp_error(&ctxt, (rc = ESLURM_DB_CONNECTION),
					   XSTRINGIFY(openapi_get_db_conn),
					   "Failed to open slurmdbd connection%s",
					   auth_error_msg);
		else
			openapi_resp_warn(&ctxt,
					  XSTRINGIFY(openapi_get_db_conn),
					  "Failed to open connection to slurmdbd%s. Response fields may not be fully populated or empty.",
					  auth_error_msg);
	} else {
		rc = data_parser_g_assign(ctxt.parser,
					  DATA_PARSER_ATTR_DBCONN_PTR,
					  ctxt.db_conn);
	}

	if (!rc)
		rc = callback(&ctxt);

	if (data_get_type(ctxt.resp) == DATA_TYPE_NULL)
		data_set_dict(ctxt.resp);

	if (op_path->flags & OP_BIND_OPENAPI_RESP_FMT)
		_populate_openapi_results(&ctxt, &query_meta);

	if (!rc)
		rc = ctxt.rc;

	FREE_NULL_LIST(ctxt.errors);
	FREE_NULL_LIST(ctxt.warnings);
	FREE_NULL_DATA_PARSER(ctxt.parser);
	FREE_NULL_DATA(ctxt.parent_path);

	return rc;
}

extern bool is_spec_generation_only(bool set)
{
	static bool is_spec_only = false;

	if (set)
		is_spec_only = true;

	return is_spec_only;
}
