/*****************************************************************************\
 *  data.c - generic data_t structures
 *****************************************************************************
 *  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.
\*****************************************************************************/

#define _ISOC99_SOURCE	/* needed for lrint */

#include <ctype.h>
#include <math.h>

#include "src/common/data.h"
#include "src/common/http.h"
#include "src/common/list.h"
#include "src/common/log.h"
#include "src/common/macros.h"
#include "src/common/read_config.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

strong_alias(_data_set_string_own, slurm__data_set_string_own);
strong_alias(data_dict_for_each_const, slurm_data_dict_for_each_const);
strong_alias(data_free, slurm_data_free);
strong_alias(data_get_string, slurm_data_get_string);
strong_alias(data_key_get, slurm_data_key_get);
strong_alias(data_key_set, slurm_data_key_set);
strong_alias(data_list_for_each_const, slurm_data_list_for_each_const);
strong_alias(data_new, slurm_data_new);
strong_alias(data_set_bool, slurm_data_set_bool);
strong_alias(data_set_dict, slurm_data_set_dict);
strong_alias(data_set_float, slurm_data_set_float);
strong_alias(data_set_int, slurm_data_set_int);
strong_alias(data_set_list, slurm_data_set_list);
strong_alias(data_set_null, slurm_data_set_null);
strong_alias(data_set_string, slurm_data_set_string);

#define DATA_DEFINE_DICT_PATH_BUFFER_SIZE 1024
#define DATA_MAGIC 0x1992189F
#define DATA_LIST_MAGIC 0x1992F89F
#define DATA_LIST_NODE_MAGIC 0x1921F89F

/* max chars PRId64 could printf(). strlen("-9223372036854775808") = 20 */
#define INT64_CHAR_MAX 20

typedef struct data_list_s data_list_t;
typedef struct data_list_node_s data_list_node_t;

typedef enum {
	TYPE_NONE = 0, /* invalid or unknown type */
	/* only for bounds checks to avoid any overlap with DATA_TYPE_* */
	TYPE_START = 0xFF00,
	TYPE_NULL, /* ECMA-262:4.3.13 NULL type */
	TYPE_LIST, /* ECMA-262:22.1 Array Object (ordered list) */
	TYPE_DICT, /* ECMA-262:23.1 Map Object (dictionary) */
	TYPE_INT_64, /*  64bit signed integer
				This exists as an convenient storage type.
				ECMA does not have an integer primitive.
				ECMA-262:7.1.4 ToInteger() returns approx
				this value with some rounding. */
	TYPE_STRING_PTR, /* ECMA-262:4.3.18 String type */
	TYPE_STRING_INLINE, /* string stored in union directly */
	TYPE_FLOAT, /* ECMA-262:6.1.6 Number type */
	TYPE_BOOL, /* ECMA-262:4.3.15 Boolean type */
	TYPE_MAX /* only for bounds checking */
} type_t;

static const struct {
	data_type_t external_type;
	type_t internal_type;
} type_map[] = {
	{ DATA_TYPE_NULL, TYPE_NULL },
	{ DATA_TYPE_LIST, TYPE_LIST },
	{ DATA_TYPE_DICT, TYPE_DICT },
	{ DATA_TYPE_INT_64, TYPE_INT_64 },
	{ DATA_TYPE_STRING, TYPE_STRING_PTR },
	{ DATA_TYPE_STRING, TYPE_STRING_INLINE },
	{ DATA_TYPE_FLOAT, TYPE_FLOAT },
	{ DATA_TYPE_BOOL, TYPE_BOOL },
};

typedef struct data_list_node_s {
	int magic;
	data_list_node_t *next;

	data_t *data;
	char *key; /* key for dictionary (only) */
} data_list_node_t;

/* Single linked list for list_u and dict_u */
typedef struct data_list_s {
	int magic;
	size_t count;

	data_list_node_t *begin;
	data_list_node_t *end;
} data_list_t;

/*
 * Data is based on the JSON data type and has the same types.
 * Data forms a tree structure.
 * Please avoid direct access of this struct and only use access functions.
 * The nature of this struct may change at any time, only pass around pointers
 * created from data_new().
 */
struct data_s {
	int magic;
	type_t type;

	union { /* append "_u" to every type to avoid reserved words */
		data_list_t *list_u;
		data_list_t *dict_u;
		int64_t int_u;
		char string_inline_u[sizeof(void *)];
		char *string_ptr_u;
		double float_u;
		bool bool_u;
	} data;
};

typedef struct {
	char *path;
	char *at;
	const char *token;
} merge_path_strings_t;

typedef struct {
	const data_t *a;
	const data_t *b;
	bool mask;
} find_dict_match_t;

typedef struct {
	size_t count;
	type_t match;
} convert_args_t;

#define CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC 0x139414ab

typedef struct {
	int magic; /* CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC */
	data_t *src;
	int64_t index;
} convert_data_foreach_list_dict_args_t;

#define PARSE_DICT_PATH_ARGS_MAGIC 0x8aa834af

typedef struct {
	int magic; /* PARSE_DICT_PATH_ARGS_MAGIC */
	data_t *found;
} dict_path_args_t;

#define PARSE_DICT_PATH_CONST_ARGS_MAGIC 0x802834af

typedef struct {
	int magic; /* PARSE_DICT_PATH_CONST_ARGS_MAGIC  */
	const data_t *found;
} dict_path_const_args_t;

#define DEFINE_DICT_PATH_ARGS_MAGIC 0x02bbafff

typedef struct {
	int magic; /* DEFINE_DICT_PATH_ARGS_MAGIC */
	data_t *found;
} dict_path_define_args_t;

static void _check_magic(const data_t *data);
static void _release(data_t *data);
static void _release_data_list_node(data_list_t *dl, data_list_node_t *dn);
static size_t _convert_tree(data_t *data, const type_t match);
static char *_type_to_string(type_t type);

static data_list_t *_data_list_new(void)
{
	data_list_t *dl = xmalloc(sizeof(*dl));
	dl->magic = DATA_LIST_MAGIC;

	log_flag(DATA, "%s: new data-list(0x%"PRIxPTR")[%zu]",
		 __func__, (uintptr_t) dl, dl->count);

	return dl;
}

static void _check_data_list_node_magic(const data_list_node_t *dn)
{
	xassert(dn);
	xassert(dn->magic == DATA_LIST_NODE_MAGIC);
	/* make sure not linking to self */
	xassert(dn->next != dn);
}

static void _check_data_list_magic(const data_list_t *dl)
{
#ifndef NDEBUG
	xassert(dl);
	xassert(dl->magic == DATA_LIST_MAGIC);

	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		data_list_node_t *end = NULL;

		if (dl->begin) {
			/* walk forwards verify */
			int c = 0;
			data_list_node_t *i = dl->begin;

			while (i) {
				c++;
				_check_data_list_node_magic(i);
				end = i;
				i = i->next;
			}

			xassert(c == dl->count);
		}

		xassert(end == dl->end);
	}
#endif /* !NDEBUG */
}

/* verify node is in parent list */
static void _check_data_list_node_parent(const data_list_t *dl,
					 const data_list_node_t *dn)
{
#ifndef NDEBUG
	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		data_list_node_t *i = dl->begin;
		while (i) {
			if (i == dn)
				return;
			i = i->next;
		}

		/* found an orphan? */
		fatal_abort("%s: unexpected orphan node", __func__);
	}
#endif /* !NDEBUG */
}

static void _release_data_list_node(data_list_t *dl, data_list_node_t *dn)
{
	_check_data_list_magic(dl);
	_check_data_list_node_magic(dn);
	_check_data_list_node_parent(dl, dn);
	data_list_node_t *prev;

	log_flag(DATA, "%s: free data-list(0x%"PRIxPTR")[%zu]",
		 __func__, (uintptr_t) dl, dl->count);

	/* walk list to find new previous */
	for (prev = dl->begin; prev && prev->next != dn; ) {
		_check_data_list_node_magic(prev);
		prev = prev->next;
		if (prev)
			_check_data_list_node_magic(prev);
	}

	if (dn == dl->begin) {
		/* at the beginning */
		xassert(!prev);
		dl->begin = dn->next;

		if (dl->end == dn) {
			dl->end = NULL;
			xassert(!dn->next);
		}
	} else if (dn == dl->end) {
		/* at the end */
		xassert(!dn->next);
		xassert(prev);
		dl->end = prev;
		prev->next = NULL;
	} else {
		/* somewhere in middle */
		xassert(prev);
		xassert(prev != dn);
		xassert(prev->next == dn);
		xassert(dl->begin != dn);
		xassert(dl->end != dn);
		prev->next = dn->next;
	}

	dl->count--;
	FREE_NULL_DATA(dn->data);
	xfree(dn->key);

	dn->magic = ~DATA_LIST_NODE_MAGIC;
	xfree(dn);
}

static void _release_data_list(data_list_t *dl)
{
	data_list_node_t *n = dl->begin, *i;
#ifndef NDEBUG
	int count = 0;
	const int init_count = dl->count;
#endif

	_check_data_list_magic(dl);

	if (!n) {
		xassert(!dl->count);
		xassert(!dl->end);
		goto finish;
	}

	xassert(dl->end);

	while((i = n)) {
		n = i->next;
		_release_data_list_node(dl, i);

#ifndef NDEBUG
		count++;
#endif
	}


#ifndef NDEBUG
	xassert(count == init_count);
#endif

finish:
	dl->magic = ~DATA_LIST_MAGIC;
	xfree(dl);
}

/*
 * Create new data list node entry
 * IN d - data type to take ownership of
 * IN key - dictionary key to dup or NULL
 */
static data_list_node_t *_new_data_list_node(data_t *d, const char *key)
{
	data_list_node_t *dn = xmalloc(sizeof(*dn));
	dn->magic = DATA_LIST_NODE_MAGIC;

	_check_magic(d);

	dn->data = d;
	if (key) {
		dn->key = xstrdup(key);

		log_flag(DATA, "%s: new dictionary entry data-list-node(0x%"PRIxPTR")[%s]=%pD",
			 __func__, (uintptr_t) dn, dn->key, dn->data);
	} else {
		log_flag(DATA, "%s: new list entry data-list-node(0x%"PRIxPTR")=%pD",
			 __func__, (uintptr_t) dn, dn->data);
	}

	return dn;
}

static void _data_list_append(data_list_t *dl, data_t *d, const char *key)
{
	data_list_node_t *n = _new_data_list_node(d, key);
	_check_data_list_magic(dl);
	_check_magic(d);

	if (dl->end) {
		xassert(!dl->end->next);
		_check_data_list_node_magic(dl->end);
		_check_data_list_node_magic(dl->begin);

		dl->end->next = n;
		dl->end = n;
	} else {
		xassert(!dl->count);
		dl->end = n;
		dl->begin = n;
	}

	dl->count++;

	if (n->key)
		log_flag(DATA, "%s: append dictionary entry data-list-node(0x%"PRIxPTR")[%s]=%pD",
			 __func__, (uintptr_t) n, n->key, n->data);
	else
		log_flag(DATA, "%s: append list entry data-list-node(0x%"PRIxPTR")=%pD",
			 __func__, (uintptr_t) n, n->data);
}

static void _data_list_prepend(data_list_t *dl, data_t *d, const char *key)
{
	data_list_node_t *n = _new_data_list_node(d, key);
	_check_data_list_magic(dl);
	_check_magic(d);

	if (dl->begin) {
		_check_data_list_node_magic(dl->begin);
		n->next = dl->begin;
		dl->begin = n;
	} else {
		xassert(!dl->count);
		dl->begin = n;
		dl->end = n;
	}

	dl->count++;

	log_flag(DATA, "%s: prepend %pD[%s]->data-list-node(0x%"PRIxPTR")[%s]=%pD",
		 __func__, d, key, (uintptr_t) n, n->key, n->data);
}

extern data_t *data_new(void)
{
	data_t *data = xmalloc(sizeof(*data));
	data->magic = DATA_MAGIC;
	data->type = TYPE_NULL;

	log_flag(DATA, "%s: new %pD", __func__, data);

	return data;
}

static void _check_magic(const data_t *data)
{
	if (!data)
		return;

	xassert(data->magic == DATA_MAGIC);

	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		xassert(data->type > TYPE_START);
		xassert(data->type < TYPE_MAX);

		if (data->type == TYPE_LIST)
			_check_data_list_magic(data->data.list_u);
		if (data->type == TYPE_DICT)
			_check_data_list_magic(data->data.dict_u);
	}
}

static void _release(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_LIST:
		_release_data_list(data->data.list_u);
		break;
	case TYPE_DICT:
		_release_data_list(data->data.dict_u);
		break;
	case TYPE_STRING_PTR:
		xfree(data->data.string_ptr_u);
		break;
	default:
		/* other types don't need to be freed */
		break;
	}

	data->type = TYPE_NONE;
}

extern void data_free(data_t *data)
{
	if (!data)
		return;

	log_flag(DATA, "%s: free %pD", __func__, data);

	_check_magic(data);
	_release(data);

	data->magic = ~DATA_MAGIC;
	data->type = TYPE_NONE;
	xfree(data);
}

extern data_type_t data_get_type(const data_t *data)
{
	if (!data)
		return DATA_TYPE_NONE;

	_check_magic(data);

	for (int i = 0; i < ARRAY_SIZE(type_map); i++)
		if (type_map[i].internal_type == data->type)
			return type_map[i].external_type;

	return DATA_TYPE_NONE;
}

extern data_t *data_set_float(data_t *data, double value)
{
	_check_magic(data);
	if (!data)
		return NULL;

	data->type = TYPE_FLOAT;
	data->data.float_u = value;

	log_flag(DATA, "%s: set %pD=%e", __func__, data, value);

	return data;
}

extern data_t *data_set_null(data_t *data)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_NULL;

	log_flag(DATA, "%s: set %pD=null", __func__, data);

	return data;
}

extern data_t *data_set_bool(data_t *data, bool value)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_BOOL;
	data->data.bool_u = value;

	log_flag(DATA, "%s: set %pD=%s",
		 __func__, data, (value ? "true" : "false"));

	return data;
}

extern data_t *data_set_int(data_t *data, int64_t value)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_INT_64;
	data->data.int_u = value;

	log_flag(DATA, "%s: set %pD=%"PRId64, __func__, data, value);

	return data;
}

static void _set_data_string_ptr(data_t *data, const size_t len,
				  char **value_ptr)
{
	data->type = TYPE_STRING_PTR;
	data->data.string_ptr_u = *value_ptr;
	*value_ptr = NULL;
	log_flag_hex(DATA, data->data.string_ptr_u, len, "%s: set string %pD",
		     __func__, data);
}

static void _set_data_string_inline(data_t *data, const size_t len,
				    const char *value)
{
	memmove(data->data.string_inline_u, value, len + 1);
	data->type = TYPE_STRING_INLINE;
	log_flag_hex(DATA, data->data.string_inline_u, len,
		     "%s: set inline string %pD", __func__, data);
}

extern data_t *data_set_string(data_t *data, const char *value)
{
	int len;

	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	if (!value) {
		data->type = TYPE_NULL;

		log_flag(DATA, "%s: set %pD=null", __func__, data);
		return data;
	}

	if ((len = strlen(value)) < sizeof(data->data.string_inline_u)) {
		_set_data_string_inline(data, len, value);
	} else {
		char *dval = xstrdup(value);
		_set_data_string_ptr(data, len, &dval);
	}

	return data;
}

extern data_t *_data_set_string_own(data_t *data, char **value_ptr)
{
	char *value;
	int len;
	_check_magic(data);

	if (!data) {
		xfree(*value_ptr);
		return NULL;
	}

	_release(data);

	value = *value_ptr;
	*value_ptr = NULL;

	if (!value) {
		data->type = TYPE_NULL;

		log_flag(DATA, "%s: set %pD=null", __func__, data);
		return data;
	}

#ifndef NDEBUG
	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		char *old_value = value;

		/* check that the string was xmalloc()ed and actually has contents */
		xassert(xsize(value) > 0);
		/*
		 * catch use after free by the caller by using the existing xfree()
		 * functionality
		 */
		value = xstrdup(value);
		/* releasing original string instead of NULLing original pointer */
		xfree(old_value);
	}
#endif

	if ((len = strlen(value)) < sizeof(data->data.string_inline_u)) {
		_set_data_string_inline(data, len, value);
		/* we don't need to keep this string alloc */
		xfree(value);
	} else {
		_set_data_string_ptr(data, len, &value);
	}

	xassert(!value);
	return data;
}

extern data_t *data_set_dict(data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_DICT;
	data->data.dict_u = _data_list_new();

	log_flag(DATA, "%s: set %pD to dictionary", __func__, data);

	return data;
}

extern data_t *data_set_list(data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_LIST;
	data->data.list_u = _data_list_new();

	log_flag(DATA, "%s: set %pD to list", __func__, data);

	return data;
}

extern data_t *data_list_append(data_t *data)
{
	data_t *ndata = NULL;
	_check_magic(data);

	xassert(data && (data->type == TYPE_LIST));
	if (!data || data->type != TYPE_LIST)
		return NULL;

	ndata = data_new();
	_data_list_append(data->data.list_u, ndata, NULL);

	log_flag(DATA, "%s: appended %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ndata);

	return ndata;
}

extern data_t *data_list_prepend(data_t *data)
{
	data_t *ndata = NULL;
	_check_magic(data);

	if (!data || data->type != TYPE_LIST)
		return NULL;

	ndata = data_new();
	_data_list_prepend(data->data.list_u, ndata, NULL);

	log_flag(DATA, "%s: prepended %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ndata);

	return ndata;
}

extern data_t *data_list_dequeue(data_t *data)
{
	data_list_node_t *n;
	data_t *ret = NULL;
	_check_magic(data);

	if (!data || data->type != TYPE_LIST)
		return NULL;

	if (!(n = data->data.list_u->begin))
		return NULL;

	_check_data_list_node_magic(n);

	/* extract out data for caller */
	SWAP(ret, n->data);

	/* remove node from list */
	_release_data_list_node(data->data.list_u, n);

	log_flag(DATA, "%s: dequeued %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ret);

	return ret;
}

static data_for_each_cmd_t _data_list_join(const data_t *src, void *arg)
{
	data_t *dst = (data_t *) arg;
	data_t *dst_entry;
	_check_magic(src);
	_check_magic(dst);
	xassert(dst->type == TYPE_LIST);

	log_flag(DATA, "%s: list join data %pD to %pD", __func__, src, dst);

	dst_entry = data_list_append(dst);
	data_copy(dst_entry, src);

	log_flag(DATA, "%s: list join %pD to %pD[%zu]=%pD",
		 __func__, src, dst, dst->data.list_u->count, dst_entry);

	 return DATA_FOR_EACH_CONT;
}

extern data_t *data_list_join(const data_t **data, bool flatten_lists)
{
	data_t *dst = data_set_list(data_new());

	for (size_t i = 0; data[i]; i++) {
		log_flag(DATA, "%s: %s list join %pD to %pD[%zu]",
			 __func__, (flatten_lists ? "flattened" : ""),
			 data[i], dst, dst->data.list_u->count);

		if (flatten_lists && (data[i]->type == TYPE_LIST))
			(void) data_list_for_each_const(data[i],
							_data_list_join, dst);
		else /* simple join */
			_data_list_join(data[i], dst);
	}

	return dst;
}

extern const data_t *data_key_get_const(const data_t *data, const char *key)
{
	const data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (!key || data->type != TYPE_DICT)
		return NULL;

	/* don't bother searching empty dictionary */
	if (!data->data.dict_u->count)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (!xstrcmp(key, i->key))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

static bool _match_string(const char *key, data_t *data, void *needle_ptr)
{
	const char *needle = needle_ptr;
	return !xstrcmp(key, needle);
}

extern data_t *data_key_get(data_t *data, const char *key)
{
	return data_dict_find_first(data, _match_string, (void *) key);
}

extern data_t *data_key_get_int(data_t *data, int64_t key)
{
	char key_str[INT64_CHAR_MAX + 1];

	(void) snprintf(key_str, sizeof(key_str), "%"PRId64, key);

	return data_key_get(data, key_str);
}

extern data_t *data_list_find_first(
	data_t *data,
	bool (*match)(const data_t *data, void *needle),
	void *needle)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_LIST);
	if (data->type != TYPE_LIST)
		return NULL;

	/* don't bother searching empty list */
	if (!data->data.list_u->count)
		return NULL;

	_check_data_list_magic(data->data.list_u);
	i = data->data.list_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (match(i->data, needle))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

extern data_t *data_dict_find_first(
	data_t *data,
	bool (*match)(const char *key, data_t *data, void *needle),
	void *needle)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (data->type != TYPE_DICT)
		return NULL;

	/* don't bother searching empty dictionary */
	if (!data->data.dict_u->count)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (match(i->key, i->data, needle))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

extern data_t *data_key_set(data_t *data, const char *key)
{
	data_t *d;

	_check_magic(data);

	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (!key || (data->type != TYPE_DICT))
		return NULL;

	if ((d = data_key_get(data, key))) {
		log_flag(DATA, "%s: overwrite existing key in %pD[%s]=%pD",
			 __func__, data, key, d);
		return d;
	}

	d = data_new();
	_data_list_append(data->data.dict_u, d, key);

	log_flag(DATA, "%s: populate new key in %pD[%s]=%pD",
		 __func__, data, key, d);

	return d;
}

extern data_t *data_key_set_int(data_t *data, int64_t key)
{
	char key_str[INT64_CHAR_MAX + 1];

	(void) snprintf(key_str, sizeof(key_str), "%"PRId64, key);

	return data_key_set(data, key_str);
}

extern bool data_key_unset(data_t *data, const char *key)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return false;

	xassert(data->type == TYPE_DICT);
	if (!key || data->type != TYPE_DICT)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (!xstrcmp(key, i->key))
			break;

		i = i->next;
	}

	if (!i) {
		log_flag(DATA, "%s: remove non-existent key in %pD[%s]",
			 __func__, data, key);
		return false;
	}

	log_flag(DATA, "%s: remove existing key in %pD[%s]=data-list-node(0x%"PRIxPTR")[%s]=%pD",
		 __func__, data, key, (uintptr_t) i, i->key, i->data);

	_release_data_list_node(data->data.dict_u, i);

	return true;
}

extern double data_get_float(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return NAN;

	xassert(data->type == TYPE_FLOAT);
	return data->data.float_u;
}

extern bool data_get_bool(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return false;

	xassert(data->type == TYPE_BOOL);
	return data->data.bool_u;
}

extern int64_t data_get_int(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	if (data->type == TYPE_NULL)
		return 0;

	xassert(data->type == TYPE_INT_64);
	return data->data.int_u;
}

extern const char *data_get_string(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;

	xassert((data->type == TYPE_STRING_PTR) ||
		(data->type == TYPE_STRING_INLINE) ||
		(data->type == TYPE_NULL));

	if (data->type == TYPE_STRING_PTR) {
		return data->data.string_ptr_u;
	} else if (data->type == TYPE_STRING_INLINE) {
		return data->data.string_inline_u;
	} else {
		return NULL;
	}
}

extern int data_get_string_converted(const data_t *d, char **buffer)
{
	_check_magic(d);
	char *_buffer = NULL;
	bool cloned;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if ((d->type != TYPE_STRING_PTR) && (d->type != TYPE_STRING_INLINE)) {
		/* copy the data and then convert it to a string type */
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_STRING) ==
		    DATA_TYPE_STRING)
			_buffer = xstrdup(data_get_string(dclone));
		FREE_NULL_DATA(dclone);
		cloned = true;
	} else {
		_buffer = xstrdup(data_get_string(d));
		if (!_buffer)
			_buffer = xstrdup("");
		cloned = false;
	}

	if (_buffer) {
		*buffer = _buffer;

		log_flag_hex(DATA, _buffer, strlen(_buffer),
			     "%s: string %sat %pD=string@0x%"PRIxPTR"[%zu]",
			     __func__, (cloned ? "conversion and cloned " : ""),
			     d, (uintptr_t) _buffer, strlen(_buffer));

		return SLURM_SUCCESS;
	}

	log_flag(DATA, "%s: %pD string conversion failed", __func__, d);

	return ESLURM_DATA_CONV_FAILED;
}

extern int data_copy_bool_converted(const data_t *d, bool *buffer)
{
	_check_magic(d);
	int rc = ESLURM_DATA_CONV_FAILED;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if (d->type != TYPE_BOOL) {
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_BOOL) ==
		    DATA_TYPE_BOOL) {
			*buffer = data_get_bool(dclone);
			rc = SLURM_SUCCESS;
		}
		FREE_NULL_DATA(dclone);

		log_flag(DATA, "%s: converted %pD=%s",
			 __func__, d, (*buffer ? "true" : "false"));
		return rc;
	}

	*buffer = data_get_bool(d);
	return SLURM_SUCCESS;
}

extern int data_get_bool_converted(data_t *d, bool *buffer)
{
	int rc;
	_check_magic(d);

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	/* assign value if converted successfully */
	rc = data_copy_bool_converted(d, buffer);
	if (!rc)
		data_set_bool(d, *buffer);

	return rc;
}

extern int data_get_int_converted(const data_t *d, int64_t *buffer)
{
	_check_magic(d);
	int rc = SLURM_SUCCESS;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if (d->type != TYPE_INT_64) {
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_INT_64) ==
		    DATA_TYPE_INT_64)
			*buffer = data_get_int(dclone);
		else
			rc = ESLURM_DATA_CONV_FAILED;
		FREE_NULL_DATA(dclone);
	} else {
		*buffer = data_get_int(d);
	}

	log_flag(DATA, "%s: converted %pD=%"PRId64, __func__, d, *buffer);

	return rc;
}

extern size_t data_get_dict_length(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	xassert(data->type == TYPE_DICT);
	return data->data.dict_u->count;
}

extern size_t data_get_list_length(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	xassert(data->type == TYPE_LIST);
	return data->data.list_u->count;
}

extern data_t *data_get_list_last(data_t *data)
{
	data_list_node_t *i;
	_check_magic(data);

	if (!data)
		return NULL;

	xassert(data->type == TYPE_LIST);
	if (data->type != TYPE_LIST)
		return NULL;

	if (!data->data.list_u->count)
		return NULL;

	i = data->data.list_u->begin;
	_check_data_list_magic(data->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);
		xassert(!i->key);

		if (!i->next) {
			log_flag(DATA, "%s: %pD[%s]=%pD",
				 __func__, data, i->key, i->data);
			return i->data;
		}

		i = i->next;
	}

	fatal_abort("%s: malformed data list", __func__);
}

extern int data_list_split_str(data_t *dst, const char *src, const char *token)
{
	char *save_ptr = NULL;
	char *tok = NULL;
	char *str = xstrdup(src);

	if (dst->type == TYPE_NULL)
		data_set_list(dst);

	xassert(dst->type == TYPE_LIST);
	if (dst->type != TYPE_LIST)
		return SLURM_ERROR;

	if (str && !str[0])
		xfree(str);

	if (!str)
		return SLURM_SUCCESS;

	tok = strtok_r(str, "/", &save_ptr);
	while (tok) {
		data_t *e = data_list_append(dst);
		xstrtrim(tok);

		data_set_string(e, tok);

		log_flag_hex(DATA, tok, strlen(tok),
			     "%s: split string from 0x%"PRIxPTR" to %pD[%zu]=%pD",
			     __func__, src, dst, dst->data.list_u->count, e);

		tok = strtok_r(NULL, "/", &save_ptr);
	}
	xfree(str);

	return SLURM_SUCCESS;
}

static data_for_each_cmd_t _foreach_join_str(const data_t *data, void *arg)
{
	char *b = NULL;
	merge_path_strings_t *args = arg;

	if (!data_get_string_converted(data, &b))
		xstrfmtcatat(args->path, &args->at, "%s%s%s",
			     (!args->path ? args->token : ""),
			     (args->at ? args->token : ""), b);

	xfree(b);

	return DATA_FOR_EACH_CONT;
}

extern int data_list_join_str(char **dst, const data_t *src, const char *token)
{
	merge_path_strings_t args = {
		.token = token,
	};

	xassert(!*dst);
	xassert(src->type == TYPE_LIST);

	if (data_list_for_each_const(src, _foreach_join_str, &args) < 0) {
		xfree(args.path);
		return SLURM_ERROR;
	}

	*dst = args.path;

	log_flag_hex(DATA, *dst, strlen(*dst),
		     "%s: %pD string joined with token %s",
		     __func__, src, token);

	return SLURM_SUCCESS;
}

extern int data_list_for_each_const(const data_t *d, DataListForFConst f, void *arg)
{
	int count = 0;
	const data_list_node_t *i;

	_check_magic(d);

	if (!d || (d->type != TYPE_LIST)) {
		error("%s: for each attempted on non-list object (0x%"PRIXPTR")",
		      __func__, (uintptr_t) d);
		return -1;
	}

	i = d->data.list_u->begin;
	_check_data_list_magic(d->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);

		xassert(!i->key);
		data_for_each_cmd_t cmd = f(i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			break;
		case DATA_FOR_EACH_DELETE:
			fatal_abort("%s: delete attempted against const",
				    __func__);
			break;
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}

		if (i)
			i = i->next;
	}

	return count;
}

extern int data_list_for_each(data_t *d, DataListForF f, void *arg)
{
	int count = 0;
	data_list_node_t *i;

	_check_magic(d);

	if (!d || (d->type != TYPE_LIST)) {
		error("%s: for each attempted on non-list %pD", __func__, d);
		return -1;
	}

	i = d->data.list_u->begin;
	_check_data_list_magic(d->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);

		xassert(!i->key);
		data_for_each_cmd_t cmd = f(i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			if (i)
				i = i->next;
			break;
		case DATA_FOR_EACH_DELETE:
		{
			data_list_node_t *idel = i;
			i = i->next;
			_release_data_list_node(d->data.list_u, idel);
			_check_data_list_magic(d->data.list_u);
			break;
		}
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}
	}

	return count;
}

extern int data_dict_for_each_const(const data_t *d, DataDictForFConst f, void *arg)
{
	int count = 0;
	const data_list_node_t *i;

	if (!d)
		return 0;

	_check_magic(d);

	if (data_get_type(d) != DATA_TYPE_DICT) {
		error("%s: for each attempted on non-dict %pD", __func__, d);
		return -1;
	}

	i = d->data.dict_u->begin;
	_check_data_list_magic(d->data.dict_u);
	while (i) {
		data_for_each_cmd_t cmd;

		_check_data_list_node_magic(i);

		cmd = f(i->key, i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			break;
		case DATA_FOR_EACH_DELETE:
			fatal_abort("%s: delete attempted against const",
				    __func__);
			break;
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}

		if (i)
			i = i->next;
	}

	return count;
}

extern int data_dict_for_each(data_t *d, DataDictForF f, void *arg)
{
	int count = 0;
	data_list_node_t *i;

	if (!d)
		return 0;

	_check_magic(d);

	if (data_get_type(d) != DATA_TYPE_DICT) {
		error("%s: for each attempted on non-dict %pD", __func__, d);
		return -1;
	}

	i = d->data.dict_u->begin;
	_check_data_list_magic(d->data.dict_u);
	while (i) {
		_check_data_list_node_magic(i);

		data_for_each_cmd_t cmd = f(i->key, i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			if (i)
				i = i->next;
			break;
		case DATA_FOR_EACH_DELETE:
		{
			data_list_node_t *idel = i;
			i = i->next;
			_release_data_list_node(d->data.list_u, idel);
			_check_data_list_magic(d->data.list_u);
			break;
		}
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}
	}

	return count;
}

static void _convert_data_string(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		break;
	case TYPE_BOOL:
		data_set_string(data, (data->data.bool_u ? "true" : "false"));
		break;
	case TYPE_NULL:
		data_set_string(data, "");
		break;
	case TYPE_FLOAT:
	{
		char *str = xstrdup_printf("%lf", data->data.float_u);
		data_set_string_own(data, str);
		break;
	}
	case TYPE_INT_64:
	{
		char *str = xstrdup_printf("%"PRId64, data->data.int_u);
		data_set_string_own(data, str);
		break;
	}
	default:
		break;
	}
}

static void _convert_data_force_bool(data_t *data)
{
	_check_magic(data);

	/* attempt to detect the type first */
	(void) data_convert_type(data, DATA_TYPE_NONE);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		/* non-empty string but not recognized format */
		data_set_bool(data, true);
		break;
	case TYPE_BOOL:
		break;
	case TYPE_NULL:
		data_set_bool(data, false);
		break;
	case TYPE_FLOAT:
		data_set_bool(data, data->data.float_u != 0);
		break;
	case TYPE_INT_64:
		data_set_bool(data, data->data.int_u != 0);
		break;
	default:
		break;
	}
}

static int _convert_data_null(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		const char *str = data_get_string(data);

		if (!str[0])
			goto convert;

		if (str[0] == '~')
			goto convert;

		if (!xstrcasecmp(str, "null"))
			goto convert;

		goto fail;
	}
	case TYPE_NULL:
		return SLURM_SUCCESS;
	default:
		return ESLURM_DATA_CONV_FAILED;
	}
fail:
	return ESLURM_DATA_CONV_FAILED;
convert:
	log_flag_hex(DATA, data_get_string(data), strlen(data_get_string(data)),
		     "%s: converted %pD->null", __func__, data);
	data_set_null(data);
	return SLURM_SUCCESS;
}

static int _convert_data_bool(data_t *data)
{
	const char *str = NULL;

	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		str = data_get_string(data);

		if (tolower(str[0]) == 'y') {
			if (!str[1] || ((tolower(str[1]) == 'e') &&
					(tolower(str[2]) == 's') &&
					(str[3] == '\0'))) {
				data_set_bool(data, true);
				goto converted;
			}
			goto fail;
		} else if (tolower(str[0]) == 't') {
			if (!str[1] || ((tolower(str[1]) == 'r') &&
					(tolower(str[2]) == 'u') &&
					(tolower(str[3]) == 'e') &&
					(str[4] == '\0'))) {
				data_set_bool(data, true);
				goto converted;
			}
			goto fail;
		} else if ((tolower(str[0]) == 'o') &&
			   (tolower(str[1]) == 'n') &&
			   (str[2] == '\0')) {
			data_set_bool(data, true);
			goto converted;
		} else if (tolower(str[0]) == 'n') {
			if (!str[1] || ((tolower(str[1]) == 'o') &&
					(str[2] == '\0'))) {
				data_set_bool(data, false);
				goto converted;
			}
			goto fail;
		} else if (tolower(str[0]) == 'f') {
			if (!str[1] || ((tolower(str[1]) == 'a') &&
					(tolower(str[2]) == 'l') &&
					(tolower(str[3]) == 's') &&
					(tolower(str[4]) == 'e') &&
					(str[5] == '\0'))) {
				data_set_bool(data, false);
				goto converted;
			}
			goto fail;
		} else if ((tolower(str[0]) == 'o') &&
			   (tolower(str[1]) == 'f') &&
			   (tolower(str[2]) == 'f') &&
			   (str[3] == '\0')) {
			data_set_bool(data, false);
			goto converted;
		}

		goto fail;
	}
	case TYPE_BOOL:
		return SLURM_SUCCESS;
	default:
		goto fail;
	}

converted:
	log_flag_hex(DATA, str, strlen(str),
		     "%s: converted %pD->%s",
		 __func__, data, (data_get_bool(data) ? "true" : "false"));
	return SLURM_SUCCESS;

fail:
	if (str)
		log_flag_hex(DATA, str, strlen(str),
			     "%s: converting %pD to bool failed",
			     __func__, data);
	else
		log_flag(DATA, "%s: converting %pD to bool failed",
			 __func__, data);
	return ESLURM_DATA_CONV_FAILED;
}

static int _convert_data_int(data_t *data, bool force)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		int64_t x;
		char end;
		const char *str = data_get_string(data);

		if (!str[0]) {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: convert empty string %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}

		if ((str[0] == '0') && (tolower(str[1]) == 'x')) {
			if (sscanf(str, "%"SCNx64"%c", &x, &end) == 1) {
				log_flag_hex(DATA, str, strlen(str),
					     "%s: converted hex number %pD->%"PRId64,
					 __func__, data, x);
				data_set_int(data, x);
				return SLURM_SUCCESS;
			}

			log_flag_hex(DATA, str, strlen(str),
				     "%s: conversion of hex string %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}

		if (!force) {
			for (const char *p = str; *p; p++) {
				if ((*p < '0') || (*p > '9')) {
					log_flag_hex(DATA, str, strlen(str),
						     "%s: rejecting non-numeric conversion of %pD to integer failed",
						     __func__, data);
					return ESLURM_DATA_CONV_FAILED;
				}
			}
		}

		if (sscanf(str, "%"SCNd64"%c", &x, &end) == 1) {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: converted %pD->%"PRId64,
				     __func__, data, x);
			data_set_int(data, x);
			return SLURM_SUCCESS;
		} else {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: conversion of %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}
	}
	case TYPE_FLOAT:
		if (force) {
			data_set_int(data, lrint(data_get_float(data)));
			return SLURM_SUCCESS;
		}
		return ESLURM_DATA_CONV_FAILED;
	case TYPE_INT_64:
		return SLURM_SUCCESS;
	case TYPE_NULL:
		if (force) {
			/*
			 * Conversion from NULL to integer is a loss of
			 * information as NULL implies value is not set where as
			 * integer 0 could just mean there is a a value zero as
			 * opposed to there be no value set. This conversion is
			 * only done when force is true as such.
			 */
			data_set_int(data, 0);
			return SLURM_SUCCESS;
		}
	default:
		return ESLURM_DATA_CONV_FAILED;
	}
}

static int _convert_data_float_from_string(data_t *data)
{
	const char *str = data_get_string(data);
	int i = 0;
	bool negative = false;

	xassert(str);

	if (str[i] == '+') {
		i++;
	} else if (str[i] == '-') {
		i++;
		negative = true;
	}

	if ((tolower(str[i]) == 'i')) {
		i++;

		if (!xstrcasecmp(&str[i], "nf") ||
		    !xstrcasecmp(&str[i], "nfinity")) {
			if (negative)
				data_set_float(data, -INFINITY);
			else
				data_set_float(data, INFINITY);

			goto converted;
		}

		goto fail;
	}

	if ((tolower(str[i]) == 'n')) {
		i++;

		if (!xstrcasecmp(&str[i], "an")) {
			if (negative)
				data_set_float(data, -NAN);
			else
				data_set_float(data, NAN);

			goto converted;
		}

		goto fail;
	}

	if ((str[i] >= '0') && (str[i] <= '9')) {
		char end;
		double x;

		if (sscanf(&str[i], "%lf%c", &x, &end) == 1) {
			if (negative)
				x *= -1;
			data_set_float(data, x);
			goto converted;
		}
	}

	goto fail;

converted:
	log_flag(DATA, "%s: converted %pD to float: %s->%lf",
		 __func__, data, str, data_get_float(data));
	return SLURM_SUCCESS;

fail:
	log_flag_hex(DATA, str, strlen(str),
		     "%s: convert %pD to double float failed", __func__, data);
	return ESLURM_DATA_CONV_FAILED;
}

static int _convert_data_float(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		return _convert_data_float_from_string(data);
	case TYPE_INT_64:
		if (data_get_int(data) == INFINITE64)
			data_set_float(data, HUGE_VAL);
		else if (data_get_int(data) == NO_VAL64)
			data_set_float(data, NAN);
		else /* attempt normal fp conversion */
			data_set_float(data, data_get_int(data));
		return SLURM_SUCCESS;
	case TYPE_FLOAT:
		return SLURM_SUCCESS;
	default:
		return ESLURM_DATA_CONV_FAILED;
	}

	return ESLURM_DATA_CONV_FAILED;
}

static data_for_each_cmd_t _convert_data_foreach_dict_list(const char *key,
							   data_t *data,
							   void *arg)
{
	data_t *src = arg;

	_check_magic(src);

	(void) data_move(data_list_append(src), data);

	return DATA_FOR_EACH_CONT;
}

static int _convert_data_dict_list(data_t *src)
{
	int rc = SLURM_SUCCESS;
	data_t *dict = data_new();

	(void) data_move(dict, src);
	(void) data_set_list(src);

	if (data_dict_for_each(dict, _convert_data_foreach_dict_list, src) < 0)
		rc = ESLURM_DATA_CONV_FAILED;

	FREE_NULL_DATA(dict);
	return rc;
}

static data_for_each_cmd_t _convert_data_foreach_list_dict(data_t *data,
							   void *arg)
{
	convert_data_foreach_list_dict_args_t *args = arg;
	xassert(args->magic == CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC);

	(void) data_move(data_key_set_int(args->src, args->index), data);
	args->index++;

	return DATA_FOR_EACH_CONT;
}

static int _convert_data_list_dict(data_t *src)
{
	int rc = SLURM_SUCCESS;
	convert_data_foreach_list_dict_args_t args = {
		.magic = CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC,
		.src = src,
	};
	data_t *list = data_new();

	(void) data_move(list, src);
	(void) data_set_dict(src);

	if (data_list_for_each(list, _convert_data_foreach_list_dict, &args) <
	    0)
		rc = ESLURM_DATA_CONV_FAILED;

	FREE_NULL_DATA(list);
	return rc;
}

extern data_type_t data_convert_type(data_t *data, data_type_t match)
{
	_check_magic(data);

	if (!data)
		return DATA_TYPE_NONE;

	switch (match) {
	case DATA_TYPE_STRING:
		_convert_data_string(data);
		break;
	case DATA_TYPE_BOOL:
		_convert_data_force_bool(data);
		break;
	case DATA_TYPE_INT_64:
		(void) _convert_data_int(data, true);
		break;
	case DATA_TYPE_FLOAT:
		(void) _convert_data_float(data);
		break;
	case DATA_TYPE_NULL:
		(void) _convert_data_null(data);
		break;
	case DATA_TYPE_NONE:
		/* If a conversion succeeds skip calling the others */
		if (!_convert_data_null(data) ||
		    !_convert_data_int(data, false) ||
		    !_convert_data_float(data) ||
		    !_convert_data_int(data, true) || !_convert_data_bool(data))
			; /* blank on purpose */

		break;
	case DATA_TYPE_DICT:
		if (data->type == TYPE_DICT)
			return DATA_TYPE_DICT;
		else if ((data->type == TYPE_LIST) &&
			 !_convert_data_list_dict(data))
			return DATA_TYPE_DICT;

		/* data_parser should be used for this conversion instead. */
		break;
	case DATA_TYPE_LIST:
		if (data->type == TYPE_LIST)
			return DATA_TYPE_LIST;
		else if ((data->type == TYPE_DICT) &&
			 !_convert_data_dict_list(data))
			return DATA_TYPE_LIST;

		/* data_parser should be used for this conversion instead. */
		break;
	case DATA_TYPE_MAX:
		fatal_abort("%s: unexpected data type", __func__);
	default:
		fatal_abort("%s: invalid conversion requested", __func__);
	}

	return data_get_type(data);
}

static data_for_each_cmd_t _convert_list_entry(data_t *data, void *arg)
{
	convert_args_t *args = arg;

	args->count += _convert_tree(data, args->match);

	return DATA_FOR_EACH_CONT;
}

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

	args->count += _convert_tree(data, args->match);

	return DATA_FOR_EACH_CONT;
}

static size_t _convert_tree(data_t *data, const type_t match)
{
	convert_args_t args = {
		.match = match,
	};
	_check_magic(data);

	if (!data)
		return 0;

	switch (data->type) {
	case TYPE_DICT:
		(void)data_dict_for_each(data, _convert_dict_entry, &args);
		break;
	case TYPE_LIST:
		(void)data_list_for_each(data, _convert_list_entry, &args);
		break;
	default:
		if (match == (int) data_convert_type(data, (int) match))
			args.count++;
		break;
	}

	return args.count;
}

extern size_t data_convert_tree(data_t *data, const data_type_t match)
{
	return _convert_tree(data, (int) match);
}

static data_for_each_cmd_t _find_dict_match(const char *key, const data_t *a,
					    void *arg)
{
	bool rc;
	find_dict_match_t *p = arg;
	const data_t *b = data_key_get_const(p->b, key);

	rc = data_check_match(a, b, p->mask);

	log_flag(DATA, "dictionary compare: %s(0x%"PRIXPTR")=%s(0x%"PRIXPTR") %s %s(0x%"PRIXPTR")=%s(0x%"PRIXPTR")",
		 key, (uintptr_t) p->a, _type_to_string(a->type), (uintptr_t) a,
		 (rc ? "\u2261" : "\u2260"), key, (uintptr_t) p->b,
		 (b ? _type_to_string(b->type) : _type_to_string(TYPE_NONE)),
		 (uintptr_t) b);

	return rc ? DATA_FOR_EACH_CONT : DATA_FOR_EACH_FAIL;
}

static bool _data_match_dict(const data_t *a, const data_t *b, bool mask)
{
	find_dict_match_t p = {
		.mask = mask,
		.a = a,
		.b = b,
	};

	if (!a || (a->type != TYPE_DICT))
		return false;

	if (!b || (b->type != TYPE_DICT))
		return false;

	_check_magic(a);
	_check_magic(b);

	if (a->data.dict_u->count != b->data.dict_u->count)
		return false;

	/* match by key and not order with dictionary */
	return (data_dict_for_each_const(a, _find_dict_match, &p) >= 0);
}

static bool _data_match_lists(const data_t *a, const data_t *b, bool mask)
{
	bool fail = false;
	const data_list_node_t *ptr_a;
	const data_list_node_t *ptr_b;

	if (!a || (a->type != TYPE_LIST))
		return false;
	if (!b || (b->type != TYPE_LIST))
		return false;

	_check_magic(a);
	_check_magic(b);

	if (a->data.list_u->count != b->data.list_u->count)
		return false;

	ptr_a = a->data.list_u->begin;
	ptr_b = b->data.list_u->begin;

	while (ptr_a && !fail) {
		_check_data_list_node_magic(ptr_a);

		if (!ptr_b && mask)
			/* ignore a if b is NULL when masking */
			continue;

		_check_data_list_node_magic(ptr_b);
		if (data_check_match(ptr_a->data, ptr_b->data, mask)) {
			ptr_a = ptr_a->next;
			ptr_b = ptr_b->next;
		} else
			fail = true;
	}

	return !fail;
}

extern bool data_check_match(const data_t *a, const data_t *b, bool mask)
{
	bool rc;

	if (a == NULL && b == NULL)
		return true;

	if (a == NULL || b == NULL)
		return false;

	_check_magic(a);
	_check_magic(b);

	if (data_get_type(a) != data_get_type(b)) {
		data_t *conv = data_copy(data_new(), b);

		if ((a->type == TYPE_NULL) || (b->type == TYPE_NULL) ||
		    (data_convert_type(conv, data_get_type(a)) !=
		     data_get_type(a))) {
			log_flag(DATA, "type mismatch: %s(0x%"PRIXPTR") != %s(0x%"PRIXPTR")",
				 _type_to_string(a->type), (uintptr_t) a,
				 _type_to_string(b->type), (uintptr_t) b);
			FREE_NULL_DATA(conv);
			return false;
		}

		rc = data_check_match(a, conv, mask);
		log_flag(DATA, "compare: %pD %s %pD (converted from %pD)",
		         a, (rc ? "=" : "!="), conv, b);

		FREE_NULL_DATA(conv);
		return rc;
	}

	switch (a->type) {
	case TYPE_NULL:
		rc = (b->type == TYPE_NULL);
		log_flag(DATA, "compare: %s(0x%"PRIXPTR") %s %s(0x%"PRIXPTR")",
			 _type_to_string(a->type), (uintptr_t) a,
			 (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b);
		return rc;
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		rc = !xstrcmp(data_get_string(a), data_get_string(b));
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%s %s %s(0x%"PRIXPTR")=%s",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_string(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_string(b));
		return rc;
	case TYPE_BOOL:
		rc = (data_get_bool(a) == data_get_bool(b));
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%s %s %s(0x%"PRIXPTR")=%s",
			 _type_to_string(a->type), (uintptr_t) a,
			 (data_get_bool(a) ? "True" : "False"),
			 (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 (data_get_bool(b) ? "True" : "False"));
		return rc;
	case TYPE_INT_64:
		rc = data_get_int(a) == data_get_int(b);
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%"PRId64" %s %s(0x%"PRIXPTR")=%"PRId64,
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_int(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_int(b));
		return rc;
	case TYPE_FLOAT:
		if (!(rc = (data_get_float(a) == data_get_float(b))) ||
		    !(rc = fuzzy_equal(data_get_float(a), data_get_float(b)))) {
			if (isnan(data_get_float(a)) ==
			    isnan(data_get_float(a)))
				rc = true;
			else if (signbit(data_get_float(a)) !=
				 signbit(data_get_float(b)))
				rc = false;
			else if (isinf(data_get_float(a)) !=
				 isinf(data_get_float(b)))
				rc = false;
			else
				rc = false;
		}

		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%e %s %s(0x%"PRIXPTR")=%e",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_float(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_float(b));
		return rc;
	case TYPE_DICT:
		rc = _data_match_dict(a, b, mask);
		log_flag(DATA, "compare dictionary: %s(0x%"PRIXPTR")[%zd] %s %s(0x%"PRIXPTR")[%zd]",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_dict_length(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_dict_length(b));
		return rc;
	case TYPE_LIST:
		rc = _data_match_lists(a, b, mask);
		log_flag(DATA, "compare list: %s(0x%"PRIXPTR")[%zd] %s %s(0x%"PRIXPTR")[%zd]",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_list_length(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_list_length(b));
		return rc;
	case TYPE_NONE:
		/* fall through */
	case TYPE_START:
		/* fall through */
	case TYPE_MAX:
		fatal_abort("%s: unexpected data type", __func__);
	}

	fatal_abort("%s: should never run", __func__);
}

static int _on_dict_path(const char *entry, bool template, void *arg)
{
	dict_path_args_t *args = arg;
	data_t *src = args->found;

	_check_magic(src);
	xassert(args->magic == PARSE_DICT_PATH_ARGS_MAGIC);
	xassert(!template);

	if (args->found->type != TYPE_DICT)
		return EINVAL;

	if (!(args->found = data_key_get(src, entry)))
		return EINVAL;

	return SLURM_SUCCESS;
}

extern data_t *data_resolve_dict_path(data_t *data, const char *path)
{
	dict_path_args_t args = {
		.magic = PARSE_DICT_PATH_ARGS_MAGIC,
		.found = data,
	};

	_check_magic(data);

	if (!data || (data->type != TYPE_DICT))
		return NULL;

	if (!url_path_walk(path, false, _on_dict_path, &args)) {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD resolved dictionary path to %pD",
			     __func__, data, args.found);
		return args.found;
	} else {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD failed to resolve dictionary path",
			     __func__, data);
		return NULL;
	}
}

static int _on_dict_path_const(const char *entry, bool template, void *arg)
{
	dict_path_const_args_t *args = arg;
	const data_t *src = args->found;

	_check_magic(src);
	xassert(args->magic == PARSE_DICT_PATH_CONST_ARGS_MAGIC);
	xassert(!template);

	if (args->found->type != TYPE_DICT)
		return EINVAL;

	if (!(args->found = data_key_get_const(src, entry)))
		return EINVAL;

	return SLURM_SUCCESS;
}

extern const data_t *data_resolve_dict_path_const(const data_t *data,
						  const char *path)
{
	dict_path_const_args_t args = {
		.magic = PARSE_DICT_PATH_CONST_ARGS_MAGIC,
		.found = data,
	};

	_check_magic(data);

	if (!data || (data->type != TYPE_DICT))
		return NULL;

	if (!url_path_walk(path, false, _on_dict_path_const, &args)) {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD resolved dictionary path to %pD",
			     __func__, data, args.found);
		return args.found;
	} else {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD failed to resolve dictionary path",
			     __func__, data);
		return NULL;
	}
}

static int _on_dict_path_define(const char *entry, bool template, void *arg)
{
	dict_path_define_args_t *args = arg;
	data_t *src = args->found;

	_check_magic(src);
	xassert(args->magic == PARSE_DICT_PATH_ARGS_MAGIC);
	xassert(!template);

	if (args->found->type == TYPE_NULL)
		data_set_dict(src);
	else if (args->found->type != TYPE_DICT)
		return EINVAL;

	if (!(args->found = data_key_set(src, entry)))
		return EINVAL;

	return SLURM_SUCCESS;
}

extern data_t *data_define_dict_path(data_t *data, const char *path)
{
	dict_path_define_args_t args = {
		.magic = PARSE_DICT_PATH_ARGS_MAGIC,
		.found = data,
	};

	_check_magic(data);

	if (!data)
		return NULL;

	if (!url_path_walk(path, false, _on_dict_path_define, &args)) {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD defined dictionary path to %pD",
			     __func__, data, args.found);
		return args.found;
	} else {
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD failed to define dictionary path",
			     __func__, data);
		return NULL;
	}
}

extern data_t *data_copy(data_t *dest, const data_t *src)
{
	if (!src)
		return NULL;

	if (!dest)
		dest = data_new();

	_check_magic(src);
	_check_magic(dest);

	log_flag(DATA, "%s: copy data %pD to %pD", __func__, src, dest);

	switch (src->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		return data_set_string(dest, data_get_string(src));
	case TYPE_BOOL:
		return data_set_bool(dest, data_get_bool(src));
	case TYPE_INT_64:
		return data_set_int(dest, data_get_int(src));
	case TYPE_FLOAT:
		return data_set_float(dest, data_get_float(src));
	case TYPE_NULL:
		return data_set_null(dest);
	case TYPE_LIST:
	{
		data_list_node_t *i = src->data.list_u->begin;

		data_set_list(dest);

		while (i) {
			_check_data_list_node_magic(i);
			xassert(!i->key);
			data_copy(data_list_append(dest), i->data);
			i = i->next;
		}

		return dest;
	}
	case TYPE_DICT:
	{
		data_list_node_t *i = src->data.dict_u->begin;

		data_set_dict(dest);

		while (i) {
			_check_data_list_node_magic(i);
			data_copy(data_key_set(dest, i->key), i->data);
			i = i->next;
		}

		return dest;
	}
	default:
		fatal_abort("%s: unexpected data type", __func__);
		return NULL;
	}
}

extern data_t *data_move(data_t *dest, data_t *src)
{
	if (!src)
		return NULL;

	if (!dest)
		dest = data_new();

	_check_magic(src);
	_check_magic(dest);

	log_flag(DATA, "%s: move data %pD to %pD", __func__, src, dest);

	memmove(&dest->data, &src->data, sizeof(src->data));
	dest->type = src->type;
	src->type = TYPE_NULL;

	return dest;
}

extern int data_retrieve_dict_path_string(const data_t *data, const char *path,
					  char **ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_get_string_converted(d, ptr_buffer);

	if (rc)
		log_flag(DATA, "%s: data %pD failed to resolve string at path:%s",
			 __func__, data, path);
	else
		log_flag_hex(DATA, *ptr_buffer, strlen(*ptr_buffer),
			 "%s: data %pD resolved string at path:%s",
			 __func__, data, path);

	return rc;
}

extern int data_retrieve_dict_path_bool(const data_t *data, const char *path,
					bool *ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_copy_bool_converted(d, ptr_buffer);

	log_flag(DATA, "%s: data %pD resolved string at path %s=%s: %s",
		 __func__, data, path,
		 (*ptr_buffer ? "true" : "false"), slurm_strerror(rc));

	return rc;
}

extern int data_retrieve_dict_path_int(const data_t *data, const char *path,
				       int64_t *ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_get_int_converted(d, ptr_buffer);

	log_flag(DATA, "%s: data %pD resolved string at path %s to %"PRId64": %s",
		 __func__, data, path, *ptr_buffer, slurm_strerror(rc));

	return rc;
}

static char *_type_to_string(type_t type)
{
	return data_type_to_string((int) type);
}

extern char *data_type_to_string(data_type_t type)
{
	switch(type) {
		case DATA_TYPE_NULL:
			return "null";
		case DATA_TYPE_LIST:
			return "list";
		case DATA_TYPE_DICT:
			return "dictionary";
		case DATA_TYPE_INT_64:
			return "64 bit integer";
		case DATA_TYPE_STRING:
			return "string";
		case DATA_TYPE_FLOAT:
			return "floating point number";
		case DATA_TYPE_BOOL:
			return "boolean";
		case DATA_TYPE_NONE:
			/* fall through */
		case DATA_TYPE_MAX:
			return "INVALID";
	}

	for (int i = 0; i < ARRAY_SIZE(type_map); i++) {
		if (type_map[i].internal_type == (int) type)
			return data_type_to_string(type_map[i].external_type);
	}

	return "INVALID";
}

extern const char *data_get_type_string(const data_t *data)
{
	if (!data)
		return "INVALID";

	for (int i = 0; i < ARRAY_SIZE(type_map); i++)
		if (type_map[i].internal_type == data->type)
			return data_type_to_string(type_map[i].external_type);

	xassert(false);
	return "INVALID";
}
