/***************************************************************************
* Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
*  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 <errno.h>

#include "slurm/slurm.h"
#include "src/common/data.h"
#include "src/common/log.h"
#include "src/common/pack.h"
#include "src/common/pack_data.h"
#include "src/common/sluid.h"
#include "src/common/slurm_protocol_pack.h"
#include "src/common/xbase64.h"
#include "src/common/xstring.h"
#include "src/interfaces/switch.h"
#include "src/lua/slurm_lua.h"
#include "src/slurmctld/node_scheduler.h"
#include "src/slurmctld/slurmscriptd.h"

/* Required Slurm plugin symbols: */
const char plugin_name[] = "switch lua plugin";
const char plugin_type[] = "switch/lua";
const uint32_t plugin_version = SLURM_VERSION_NUMBER;

/* Push the arguments and return how many, or -1 to abandon the call. */
typedef int (*lua_push_f)(lua_State *L, void *ctx);

/* Consume the results, which _run_lua() pops afterwards. */
typedef int (*lua_handle_f)(lua_State *L, void *ctx);

/* One job's call, in slurmctld or in the slurmscriptd child */
typedef struct {
	switch_complete_cb_t complete_cb;
	uint32_t job_id;
	buf_t *job_info_buf;
	job_info_msg_t *job_info_msg;
	data_t *jobinfo;
	int rc;
	sluid_t sluid;
	switch_start_cb_t start_cb;
	bool teardown_needed;
} switch_lua_job_t;

static char *lua_script_path;
static time_t lua_script_last_loaded = (time_t) 0;
static lua_State *L = NULL;
static bool block_job_complete = false;
static bool setup_special_steps = false;

static const char *req_fxns[] = { NULL };

static const char log_ctx_key[] = "switch/lua log context";

/* Prefix log lines from the script with lua_function and job_id. */
static void _set_log_ctx(lua_State *L, const char *lua_function,
			 uint32_t job_id)
{
	char *ctx = NULL;

	if (job_id)
		ctx = xstrdup_printf("%s JobId=%u", lua_function, job_id);
	else
		ctx = xstrdup(lua_function);

	lua_pushstring(L, ctx);
	lua_setfield(L, LUA_REGISTRYINDEX, log_ctx_key);
	xfree(ctx);
}

static void _clear_log_ctx(lua_State *L)
{
	lua_pushnil(L);
	lua_setfield(L, LUA_REGISTRYINDEX, log_ctx_key);
}

static char *_log_prefix(lua_State *L)
{
	char *prefix = NULL;
	const char *ctx;

	lua_getfield(L, LUA_REGISTRYINDEX, log_ctx_key);
	if ((ctx = lua_tostring(L, -1)))
		prefix = xstrdup_printf("%s: %s", plugin_type, ctx);
	else
		prefix = xstrdup(plugin_type);
	lua_pop(L, 1);

	return prefix;
}

/* slurm.log([level,] msg), with the levels of the generic slurm.log */
static int _log_lua_msg(lua_State *L)
{
	int level = 0;
	const char *msg;
	char *prefix;

	if (lua_gettop(L) > 1) {
		level = (int) lua_tonumber(L, 1);
		msg = lua_tostring(L, 2);
	} else {
		msg = lua_tostring(L, 1);
	}

	prefix = _log_prefix(L);

	if (level > 4)
		debug4("%s: %s", prefix, msg);
	else if (level == 4)
		debug3("%s: %s", prefix, msg);
	else if (level == 3)
		debug2("%s: %s", prefix, msg);
	else if (level == 2)
		debug("%s: %s", prefix, msg);
	else if (level == 1)
		verbose("%s: %s", prefix, msg);
	else if (level == 0)
		info("%s: %s", prefix, msg);

	xfree(prefix);
	return 0;
}

/* slurm.error(msg) */
static int _log_lua_error(lua_State *L)
{
	const char *msg = lua_tostring(L, 1);
	char *prefix = _log_prefix(L);

	error("%s: %s", prefix, msg);

	xfree(prefix);
	return 0;
}

/* slurm.user_msg() has no user to reach here, so it logs instead. */
static int _log_lua_user_msg(lua_State *L)
{
	const char *msg = lua_tostring(L, 1);
	char *prefix = _log_prefix(L);

	info("%s: user message: %s", prefix, msg);

	xfree(prefix);
	return 0;
}

static const struct luaL_Reg slurm_functions[] = {
	{ "log", _log_lua_msg },
	{ "error", _log_lua_error },
	{ "user_msg", _log_lua_user_msg },
	{ NULL, NULL },
};

static void _loadscript_extra(lua_State *L)
{
	slurm_lua_table_register(L, NULL, slurm_functions);
	/* slurm_switch_job_complete() returns this to retry with nodes held */
	lua_pushnumber(L, EAGAIN);
	lua_setfield(L, -2, "EAGAIN");
	/* Must be done after the slurm_functions are registered */
	lua_setglobal(L, "slurm");

	/* print() as the Lua manual describes it, but into the log */
	luaL_loadstring(L, "local t = {} "
			   "for i = 1, select('#', ...) do "
			   "t[i] = tostring((select(i, ...))) "
			   "end "
			   "slurm.log(0, table.concat(t, '\\t'))");
	lua_setglobal(L, "print");
}

/* Required for switch plugins: */
const uint32_t plugin_id = SWITCH_PLUGIN_LUA;

/* Call a no-argument Lua function; undefined or failing counts as false. */
static bool _call_bool_function(const char *lua_function)
{
	bool ret = false;
	int rc = SLURM_SUCCESS;
	char *err = NULL;

	if ((rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path,
				       req_fxns, &lua_script_last_loaded,
				       _loadscript_extra, NULL))) {
		error("switch/lua: %s: failed to load script", __func__);
		goto out;
	}

	lua_getglobal(L, lua_function);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		goto out;
	}

	_set_log_ctx(L, lua_function, 0);
	rc = slurm_lua_pcall(L, 0, 1, &err, __func__);
	_clear_log_ctx(L);
	if (rc) {
		error("%s: %s: %s failed: %s", plugin_type, lua_script_path,
		      lua_function, err);
		xfree(err);
		goto out;
	}

	ret = lua_toboolean(L, -1);
	lua_pop(L, 1);

out:
	return ret;
}

extern int init(void)
{
	int rc = SLURM_SUCCESS;

	if (!running_in_slurmctld() && !running_in_slurmstepd() &&
	    !run_in_daemon(IS_SLURMSCRIPTD))
		return SLURM_SUCCESS;

	lua_script_path = get_extra_conf_path("switch.lua");

	if ((rc = slurm_lua_init()) != SLURM_SUCCESS)
		return rc;

	/* A slurmscriptd child only runs switch_lua_child_run() */
	if (run_in_daemon(IS_SLURMSCRIPTD))
		return SLURM_SUCCESS;

	rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path, req_fxns,
				  &lua_script_last_loaded, _loadscript_extra,
				  NULL);

	if (rc != SLURM_SUCCESS)
		return rc;

	block_job_complete =
		_call_bool_function("slurm_switch_block_job_complete");
	setup_special_steps =
		_call_bool_function("slurm_switch_setup_special_steps");

	return SLURM_SUCCESS;
}

extern void fini(void)
{
	if (L) {
		lua_close(L);
		L = NULL;
	}
	slurm_lua_fini();
	xfree(lua_script_path);
}

static int _lua_step_rec_field(lua_State *L, const stepd_step_rec_t *step,
			       const char *name)
{
	if (!step) {
		error("%s: step is NULL", __func__);
		lua_pushnil(L);
	} else if (!xstrcmp(name, "job_id")) {
		lua_pushinteger(L, step->step_id.job_id);
	} else if (!xstrcmp(name, "partition")) {
		if (step->msg && step->msg->cred && step->msg->cred->arg)
			lua_pushstring(L, step->msg->cred->arg->job_partition);
		else
			lua_pushnil(L);
	} else if (!xstrcmp(name, "sluid")) {
		char sluid_str[SLUID_STR_BYTES];

		print_sluid(step->step_id.sluid, sluid_str, sizeof(sluid_str));
		lua_pushstring(L, sluid_str);
	} else {
		lua_pushnil(L);
	}

	return 1;
}

static int _lua_step_rec_field_index(lua_State *L)
{
	const char *name = luaL_checkstring(L, 2);
	stepd_step_rec_t *step;

	lua_getmetatable(L, -2);
	lua_getfield(L, -1, "_step_rec_ptr");
	step = lua_touserdata(L, -1);

	return _lua_step_rec_field(L, step, name);
}

static void _lua_push_step_rec(stepd_step_rec_t *step, lua_State *L)
{
	/* A table whose fields _lua_step_rec_field_index() reads from step */
	lua_newtable(L);
	lua_newtable(L);
	lua_pushcfunction(L, _lua_step_rec_field_index);
	lua_setfield(L, -2, "__index");
	lua_pushlightuserdata(L, step);
	lua_setfield(L, -2, "_step_rec_ptr");
	lua_setmetatable(L, -2);
}

extern int switch_p_save(void)
{
	return SLURM_SUCCESS;
}

extern int switch_p_restore(bool recover)
{
	return SLURM_SUCCESS;
}

/* jobinfo is a data_t, packed as an exists flag followed by pack_data(). */
extern void switch_p_jobinfo_pack(void *job_info, buf_t *buffer,
				  uint16_t protocol_version)
{
	uint32_t start;

	if (!job_info) {
		packbool(false, buffer);
		return;
	}

	start = get_buf_offset(buffer);
	packbool(true, buffer);
	if (pack_data(job_info, protocol_version, buffer)) {
		error("switch/lua: %s: failed to pack jobinfo, dropping it",
		      __func__);
		set_buf_offset(buffer, start);
		packbool(false, buffer);
	}
}

extern int switch_p_jobinfo_unpack(void **job_info, buf_t *buffer,
				   uint16_t protocol_version)
{
	bool exists;
	data_t *data = NULL;

	xassert(job_info);

	*job_info = NULL;
	safe_unpackbool(&exists, buffer);
	if (!exists)
		return SLURM_SUCCESS;

	data = data_new();
	if (unpack_data(data, protocol_version, buffer))
		goto unpack_error;

	*job_info = data;
	return SLURM_SUCCESS;
unpack_error:
	FREE_NULL_DATA(data);
	return SLURM_ERROR;
}

extern void switch_p_jobinfo_free(job_record_t *job_ptr)
{
	xassert(job_ptr);
	FREE_NULL_DATA(job_ptr->switch_jobinfo);
}

/* switch/lua stepinfo is just a copy of the jobinfo data_t */
extern int switch_p_stepinfo_build(void **step_info, void *switch_jobinfo,
				   step_record_t *step_ptr)
{
	data_t *data_step = NULL;

	if (!step_info || !switch_jobinfo)
		return SLURM_SUCCESS;

	data_step = data_new();
	if (!data_copy(data_step, switch_jobinfo)) {
		error("switch/lua: %s: failed to copy jobinfo to stepinfo",
		      __func__);
		FREE_NULL_DATA(data_step);
		return SLURM_ERROR;
	}
	*step_info = data_step;

	return SLURM_SUCCESS;
}

extern void switch_p_stepinfo_duplicate(void *source, void **dest)
{
	data_t *data_step = NULL;

	if (!source || !dest)
		return;

	data_step = data_new();
	if (!data_copy(data_step, source)) {
		error("switch/lua: %s: failed to duplicate stepinfo", __func__);
		FREE_NULL_DATA(data_step);
		return;
	}
	*dest = data_step;
}

extern void switch_p_stepinfo_free(void *step_info)
{
	FREE_NULL_DATA(step_info);
}

extern void switch_p_stepinfo_pack(void *step_info, buf_t *buffer,
				   uint16_t protocol_version)
{
	switch_p_jobinfo_pack(step_info, buffer, protocol_version);
}

extern int switch_p_stepinfo_unpack(void **step_info, buf_t *buffer,
				    uint16_t protocol_version)
{
	return switch_p_jobinfo_unpack(step_info, buffer, protocol_version);
}

/*
 * Whether slurm_switch_step_init() also runs for the batch and interactive
 * steps, as slurm_switch_setup_special_steps() answered at load.
 */
extern bool switch_p_setup_special_steps(void)
{
	return setup_special_steps;
}

/* Interpret numeric response from a lua function. */
static int _get_lua_rc(lua_State *L, const char *lua_function, int index)
{
	int rc;

	if (lua_isnumber(L, index)) {
		rc = lua_tonumber(L, index);
	} else {
		error("switch/lua: %s: non-numeric return code, assuming success",
		      lua_function);
		return SLURM_SUCCESS;
	}
	if (rc) {
		const char *msg = rc > 0 ? "Not enforced" : "Enforced";
		error("switch/lua: %s: reported failure (%d), %s",
		      lua_function, rc, msg);
	}
	if (rc > 0)
		rc = SLURM_SUCCESS;
	return rc;
}

static data_t *_get_data_stepinfo(stepd_step_rec_t *step_ptr)
{
	if (!step_ptr || !step_ptr->switch_step || !step_ptr->switch_step->data)
		return NULL;
	return (data_t *) step_ptr->switch_step->data;
}

/* Runs in slurmstepd once per node for every normal step. */
extern int switch_p_job_preinit(stepd_step_rec_t *step)
{
	int rc = SLURM_SUCCESS;
	const char *lua_function = "slurm_switch_step_preinit";
	data_t *data = NULL;
	char *err = NULL;
	int top;

	/* The job was not set up by slurm_switch_job_start() */
	if (!(data = _get_data_stepinfo(step)))
		return SLURM_SUCCESS;

	if ((rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path,
				       req_fxns, &lua_script_last_loaded,
				       _loadscript_extra, NULL))) {
		error("switch/lua: %s: failed to load script", __func__);
		goto end;
	}

	lua_getglobal(L, lua_function);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		rc = SLURM_SUCCESS;
		goto end;
	}

	_lua_push_step_rec(step, L);

	top = lua_gettop(L);
	if (slurm_lua_from_data(L, data)) {
		error("switch/lua: %s: failed to push switch_stepinfo",
		      __func__);
		lua_settop(L, top);
		lua_pushnil(L);
	}

	_set_log_ctx(L, lua_function, step->step_id.job_id);
	rc = slurm_lua_pcall(L, 2, 1, &err, __func__);
	_clear_log_ctx(L);
	if (rc) {
		error("%s: %s: %s failed: %s", plugin_type, lua_script_path,
		      lua_function, err);
		xfree(err);

		/* if a script fails, don't blow up the job start */
		rc = SLURM_SUCCESS;
	} else {
		rc = _get_lua_rc(L, lua_function, -1);
		lua_pop(L, 1);
	}

end:
	return rc;
}

static int _apply_env_table(lua_State *L, char ***env)
{
	int rc = SLURM_SUCCESS;
	int table;

	if (lua_isnoneornil(L, -1)) {
		lua_pop(L, 1);
		return SLURM_SUCCESS;
	}

	if (!lua_istable(L, -1)) {
		error("switch/lua: expected a table of env vars, got: %s",
		      luaL_typename(L, -1));
		lua_pop(L, 1);
		return SLURM_ERROR;
	}

	table = lua_gettop(L);

	lua_pushnil(L);

	while (lua_next(L, table)) {
		/* stack: -1 value, -2 name */
		const char *name, *value = NULL;

		if (lua_type(L, -2) != LUA_TSTRING) {
			error("switch/lua: %s: ignoring non-string name of type %s",
			      __func__, luaL_typename(L, -2));
			lua_pop(L, 1);
			continue;
		}

		name = lua_tostring(L, -2);

		switch (lua_type(L, -1)) {
		case LUA_TSTRING:
		case LUA_TNUMBER:
			value = lua_tostring(L, -1);
			break;
		case LUA_TBOOLEAN:
			if (lua_toboolean(L, -1))
				value = "1";
			else
				unsetenvp(*env, name);
			break;
		default:
			error("switch/lua: %s: skipping %s, unsupported value or type: %s",
			      __func__, name, luaL_typename(L, -1));
			rc = SLURM_ERROR;
			break;
		}

		if (value && !env_array_overwrite(env, name, value)) {
			error("switch/lua: %s: failed to set: %s", __func__,
			      name);
			rc = SLURM_ERROR;
		}

		/* Pop the value, leave the key for the next lua_next(). */
		lua_pop(L, 1);
	}

	lua_pop(L, 1);

	return rc;
}

/*
 * Runs in slurmstepd once per node for every normal step, and for the batch
 * and interactive steps if slurm_switch_setup_special_steps() returned true.
 * The script returns a code and a table of environment variables to set.
 */
extern int switch_p_job_init(stepd_step_rec_t *step)
{
	int rc = SLURM_SUCCESS;
	const char *lua_function = "slurm_switch_step_init";
	data_t *data = NULL;
	char *err = NULL;
	int top;

	/* The job was not set up by slurm_switch_job_start() */
	if (!(data = _get_data_stepinfo(step)))
		return SLURM_SUCCESS;

	if ((rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path,
				       req_fxns, &lua_script_last_loaded,
				       _loadscript_extra, NULL))) {
		error("switch/lua: %s: failed to load script", __func__);
		goto end;
	}

	lua_getglobal(L, lua_function);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		rc = SLURM_SUCCESS;

		goto end;
	}

	_lua_push_step_rec(step, L);

	top = lua_gettop(L);
	if (slurm_lua_from_data(L, data)) {
		error("switch/lua: %s: failed to push switch_stepinfo",
		      __func__);
		lua_settop(L, top);
		lua_pushnil(L);
	}

	_set_log_ctx(L, lua_function, step->step_id.job_id);
	rc = slurm_lua_pcall(L, 2, 2, &err, __func__);
	_clear_log_ctx(L);
	if (rc) {
		error("%s: %s: %s failed: %s", plugin_type, lua_script_path,
		      lua_function, err);
		xfree(err);
		/* if a script fails, don't blow up the job start */
		rc = SLURM_SUCCESS;
		goto end;
	} else {
		rc = _get_lua_rc(L, lua_function, -2);

		/* apply env changes, side effect is popping the table */
		if (_apply_env_table(L, &step->env)) {
			error("switch/lua: %s: failed to apply env updates",
			      lua_function);
		}

		lua_pop(L, 1);
	}
end:
	return rc;
}

/*
 * Teardown counterpart of switch_p_job_preinit(). A negative return drains the
 * node; a positive one or a script error is only logged.
 */
extern int switch_p_job_postfini(stepd_step_rec_t *step)
{
	int rc = SLURM_SUCCESS;
	const char *lua_function = "slurm_switch_step_postfini";
	data_t *data = NULL;
	char *err = NULL;
	int top;

	/* The job was not set up by slurm_switch_job_start() */
	if (!(data = _get_data_stepinfo(step)))
		return SLURM_SUCCESS;

	if ((rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path,
				       req_fxns, &lua_script_last_loaded,
				       _loadscript_extra, NULL))) {
		error("switch/lua: %s: failed to load script", __func__);
		goto end;
	}

	lua_getglobal(L, lua_function);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		rc = SLURM_SUCCESS;
		goto end;
	}

	_lua_push_step_rec(step, L);
	top = lua_gettop(L);
	if (slurm_lua_from_data(L, data)) {
		error("switch/lua: %s: failed to push switch_stepinfo",
		      __func__);
		lua_settop(L, top);
		lua_pushnil(L);
	}

	_set_log_ctx(L, lua_function, step->step_id.job_id);
	rc = slurm_lua_pcall(L, 2, 1, &err, __func__);
	_clear_log_ctx(L);
	if (rc) {
		error("%s: %s: %s failed: %s", plugin_type, lua_script_path,
		      lua_function, err);
		xfree(err);
		/* if a script fails, don't drain all the nodes */
		rc = SLURM_SUCCESS;
	} else {
		rc = _get_lua_rc(L, lua_function, -1);
		lua_pop(L, 1);
	}

end:
	return rc;
}

extern int switch_p_job_attach(void *stepinfo, char ***env, uint32_t nodeid,
			       uint32_t procid, uint32_t nnodes,
			       uint32_t nprocs, uint32_t rank)
{
	return SLURM_SUCCESS;
}

extern int switch_p_job_step_complete(void *stepinfo, char *nodelist)
{
	return SLURM_SUCCESS;
}

/*
 * Snapshot the job for a slurmscriptd child. Needs the caller's locks; the
 * buffer outlives the job record.
 */
static buf_t *_pack_job_buf(job_record_t *job_ptr)
{
	slurm_msg_t msg = {
		.auth = SLURM_MSG_AUTH_INIT_AS_INTERNAL,
		.protocol_version = SLURM_PROTOCOL_VERSION,
	};
	list_t *job_ids = list_create(NULL);
	buf_t *info_buf;

	list_append(job_ids, &job_ptr->job_id);
	info_buf = pack_spec_jobs(&msg, job_ids, SHOW_DETAIL);
	FREE_NULL_LIST(job_ids);

	return info_buf;
}

/*
 * Load the script into a new lua_State and call lua_function, once per
 * slurmscriptd child. An undefined function returns SLURM_SUCCESS and leaves
 * ctx untouched.
 */
static int _run_lua(const char *lua_function, uint32_t job_id, int nresults,
		    lua_push_f push, lua_handle_f handle, void *ctx)
{
	lua_State *L = NULL;
	time_t load_time = 0;
	int rc, nargs;
	char *err = NULL;

	if ((rc = slurm_lua_loadscript(&L, "switch/lua", lua_script_path,
				       req_fxns, &load_time, _loadscript_extra,
				       NULL))) {
		error("switch/lua: %s: failed to load script", __func__);
		goto end;
	}

	lua_getglobal(L, lua_function);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		rc = SLURM_SUCCESS;
		goto end;
	}

	if ((nargs = push(L, ctx)) < 0) {
		lua_settop(L, 0);
		rc = SLURM_ERROR;
		goto end;
	}

	_set_log_ctx(L, lua_function, job_id);
	rc = slurm_lua_pcall(L, nargs, nresults, &err, __func__);
	_clear_log_ctx(L);
	if (rc) {
		error("%s: %s: %s failed: %s", plugin_type, lua_script_path,
		      lua_function, err);
		xfree(err);
		rc = SLURM_ERROR;
		goto end;
	}

	rc = handle(L, ctx);
	lua_pop(L, nresults);

end:
	if (L)
		lua_close(L);

	return rc;
}

static int _push_job_info(lua_State *L, void *ctx)
{
	switch_lua_job_t *job = ctx;

	slurm_lua_push_job_info(&job->job_info_msg->job_array[0], L);

	return 1;
}

/* Push the job, and its jobinfo or nil */
static int _push_job_complete_args(lua_State *L, void *ctx)
{
	switch_lua_job_t *job = ctx;

	_push_job_info(L, ctx);

	if (!job->jobinfo) {
		lua_pushnil(L);
	} else if (slurm_lua_from_data(L, job->jobinfo)) {
		error("switch/lua: slurm_switch_job_complete(): failed to push jobinfo for JobId=%u",
		      job->job_id);
		return -1;
	}

	return 2;
}

static int _handle_job_start(lua_State *L, void *ctx)
{
	switch_lua_job_t *job = ctx;

	/* stack: -2 return code, -1 jobinfo dictionary or nil */
	if (lua_isnumber(L, -2)) {
		job->rc = lua_tonumber(L, -2);
	} else {
		error("switch/lua: slurm_switch_job_start(): non-numeric return code");
		job->rc = SLURM_ERROR;
	}

	if (!lua_isnoneornil(L, -1)) {
		bool refused = false;

		if (slurm_lua_to_data(L, &job->jobinfo)) {
			error("switch/lua: slurm_switch_job_start(): failed to parse return");
			refused = true;
		} else {
			/* Fail setup if returned data is un-packable. */
			buf_t *buf = init_buf(BUF_SIZE);

			if (pack_data(job->jobinfo, SLURM_PROTOCOL_VERSION,
				      buf)) {
				error("switch/lua: slurm_switch_job_start(): jobinfo is too large or too deeply nested to be saved");
				refused = true;
			}
			FREE_NULL_BUFFER(buf);
		}

		if (refused) {
			/* A successful setup still needs its teardown. */
			job->teardown_needed = (job->rc == SLURM_SUCCESS);
			FREE_NULL_DATA(job->jobinfo);
			job->rc = SLURM_ERROR;
		}
	}

	return job->rc;
}

static int _handle_job_complete(lua_State *L, void *ctx)
{
	switch_lua_job_t *job = ctx;

	/* Pass EAGAIN through; _get_lua_rc() maps other positives to success */
	if (lua_isnumber(L, -1) && ((int) lua_tonumber(L, -1) == EAGAIN))
		job->rc = EAGAIN;
	else
		job->rc = _get_lua_rc(L, "slurm_switch_job_complete", -1);

	return job->rc;
}

/* A job that cannot be packed fails in the slurmscriptd child. */
static switch_lua_job_t *_job_args_create(job_record_t *job_ptr)
{
	switch_lua_job_t *job = xmalloc(sizeof(*job));

	if (!(job->job_info_buf = _pack_job_buf(job_ptr)))
		error("switch/lua: %s: failed to pack %pJ", __func__, job_ptr);

	job->sluid = job_ptr->step_id.sluid;
	job->job_id = job_ptr->job_id;
	job->rc = SLURM_SUCCESS;

	return job;
}

static void _job_args_destroy(switch_lua_job_t *job)
{
	if (!job)
		return;

	FREE_NULL_BUFFER(job->job_info_buf);
	xfree(job);
}

/*
 * Run a script function in the slurmscriptd child, and return its exit code.
 * job_buf holds what slurmctld packed after the job info.
 */
extern int switch_lua_child_run(char *function, uint32_t job_id,
				job_info_msg_t *job_info, buf_t *job_buf,
				char **resp)
{
	switch_lua_job_t job = {
		.job_id = job_id,
		.job_info_msg = job_info,
		.rc = SLURM_SUCCESS,
	};
	buf_t *buf = NULL;
	int rc;

	if (!job_info || !job_info->record_count) {
		error("switch/lua: %s(): no job info for JobId=%u", function,
		      job_id);
		return 1;
	}

	if (!xstrcmp(function, "slurm_switch_job_complete")) {
		if (!job_buf ||
		    switch_p_jobinfo_unpack((void **) &job.jobinfo, job_buf,
					    SLURM_PROTOCOL_VERSION)) {
			error("switch/lua: %s(): failed to unpack jobinfo for JobId=%u",
			      function, job_id);
			return 1;
		}
		rc = _run_lua(function, job_id, 1, _push_job_complete_args,
			      _handle_job_complete, &job);
		FREE_NULL_DATA(job.jobinfo);
		if (rc == EAGAIN)
			return EAGAIN;
		return rc ? 1 : 0;
	}

	if (xstrcmp(function, "slurm_switch_job_start")) {
		error("switch/lua: %s: unknown function %s", __func__,
		      function);
		return 1;
	}

	rc = _run_lua(function, job_id, 2, _push_job_info, _handle_job_start,
		      &job);

	/* Return teardown_needed and the jobinfo in resp */
	buf = init_buf(BUF_SIZE);
	pack8(job.teardown_needed, buf);
	pack8(job.jobinfo ? 1 : 0, buf);
	if (job.jobinfo &&
	    pack_data(job.jobinfo, SLURM_PROTOCOL_VERSION, buf)) {
		error("switch/lua: %s(): failed to pack jobinfo for JobId=%u",
		      function, job_id);
		rc = SLURM_ERROR;
	}
	*resp = xbase64_encode((uint8_t *) get_buf_data(buf),
			       get_buf_offset(buf));
	FREE_NULL_BUFFER(buf);
	FREE_NULL_DATA(job.jobinfo);

	return rc ? 1 : 0;
}

/* Read what switch_lua_child_run() returned for a setup */
static int _unpack_start_resp(switch_lua_job_t *job, char *resp)
{
	uint8_t *data = NULL;
	uint8_t teardown_needed = 0, has_jobinfo = 0;
	buf_t *buf;
	int len;

	if (!resp || ((len = xbase64_decode(&data, resp)) < 0))
		return SLURM_ERROR;

	buf = create_buf((char *) data, len);
	safe_unpack8(&teardown_needed, buf);
	safe_unpack8(&has_jobinfo, buf);
	job->teardown_needed = teardown_needed;
	if (has_jobinfo) {
		job->jobinfo = data_new();
		if (unpack_data(job->jobinfo, SLURM_PROTOCOL_VERSION, buf))
			goto unpack_error;
	}
	FREE_NULL_BUFFER(buf);

	return SLURM_SUCCESS;

unpack_error:
	FREE_NULL_DATA(job->jobinfo);
	FREE_NULL_BUFFER(buf);
	return SLURM_ERROR;
}

static void _undo_done(void *arg, int status, char *resp, bool lost)
{
	switch_lua_job_t *job = arg;

	if (lost)
		error("switch/lua: slurm_switch_job_complete(): teardown of the late setup of JobId=%u was cut off",
		      job->job_id);
	else if (WEXITSTATUS(status))
		error("switch/lua: slurm_switch_job_complete(): teardown of the late setup of JobId=%u failed, exit status %u",
		      job->job_id, WEXITSTATUS(status));
	else
		info("switch/lua: slurm_switch_job_complete(): tore down the late setup of JobId=%u",
		     job->job_id);

	_job_args_destroy(job);
}

/*
 * A setup that was killed, or did not exit, reports nothing. slurmctld then
 * treats it as one that timed out.
 */
static void _start_done(void *arg, int status, char *resp, bool lost)
{
	switch_lua_job_t *job = arg;
	switch_start_ret_t ret;
	bool undo;

	if (lost) {
		info("switch/lua: slurm_switch_job_start(): setup of JobId=%u was cut off",
		     job->job_id);
		_job_args_destroy(job);
		return;
	}

	job->rc = WEXITSTATUS(status) ? SLURM_ERROR : SLURM_SUCCESS;
	if (_unpack_start_resp(job, resp)) {
		error("switch/lua: slurm_switch_job_start(): bad setup response for JobId=%u, exit status %u",
		      job->job_id, WEXITSTATUS(status));
		job->teardown_needed = true;
		job->rc = SLURM_ERROR;
	}

	/* start_cb() takes the slurmctld locks */
	ret = job->start_cb(job->sluid, job->rc, job->jobinfo,
			    job->teardown_needed);

	undo = ((ret == SWITCH_START_UNDO) && job->job_info_buf &&
		(((job->rc == SLURM_SUCCESS) && job->jobinfo) ||
		 job->teardown_needed));

	/* Hand the teardown the jobinfo of the late setup, if any */
	if (undo)
		switch_p_jobinfo_pack(job->jobinfo, job->job_info_buf,
				      SLURM_PROTOCOL_VERSION);

	if (ret != SWITCH_START_KEPT)
		FREE_NULL_DATA(job->jobinfo);

	if (undo) {
		slurmscriptd_run_switch_lua(job->job_id,
					    "slurm_switch_job_complete",
					    switch_get_timeout(),
					    job->job_info_buf, _undo_done, job);
		return;
	}

	_job_args_destroy(job);
}

/* A teardown that was killed, or did not exit, is left to switch_timeout */
static void _complete_done(void *arg, int status, char *resp, bool lost)
{
	switch_lua_job_t *job = arg;
	int rc;

	if (lost) {
		info("switch/lua: slurm_switch_job_complete(): teardown of JobId=%u was cut off",
		     job->job_id);
		_job_args_destroy(job);
		return;
	}

	if (!WEXITSTATUS(status))
		rc = SLURM_SUCCESS;
	else if (WEXITSTATUS(status) == EAGAIN)
		rc = EAGAIN;
	else
		rc = SLURM_ERROR;

	job->complete_cb(job->sluid, rc);

	_job_args_destroy(job);
}

/*
 * Run slurm_switch_job_start() in a slurmscriptd child. A nil jobinfo leaves
 * the job unmanaged. A failure is not torn down, so the script must undo its
 * own work, unless it succeeded and only its jobinfo was refused, or the call
 * exited without a usable response.
 */
extern int switch_p_job_start(job_record_t *job_ptr, bool test_only,
			      switch_start_cb_t start, bool *async)
{
	switch_lua_job_t *job;

	if (test_only)
		return SLURM_SUCCESS;

	/* Only jobs that request --network are set up */
	if (!job_ptr->network || !job_ptr->network[0])
		return SLURM_SUCCESS;

	job = _job_args_create(job_ptr);
	job->start_cb = start;

	slurmscriptd_run_switch_lua(job->job_id, "slurm_switch_job_start",
				    switch_get_timeout(), job->job_info_buf,
				    _start_done, job);

	*async = true;

	return SLURM_SUCCESS;
}

/*
 * Run slurm_switch_job_complete() with the job's jobinfo in a slurmscriptd
 * child as slurmctld deallocates the nodes. Success releases them, slurm.EAGAIN
 * retries later with them held, and any other failure drains them.
 */
extern int switch_p_job_complete(job_record_t *job_ptr,
				 switch_complete_cb_t complete,
				 switch_complete_mode_t *mode)
{
	switch_lua_job_t *job;

	/* Without jobinfo, only an abandoned setup is torn down or retried. */
	if (!job_ptr->switch_jobinfo &&
	    (job_ptr->switch_st.state != SWITCH_STATE_START_ABANDONED) &&
	    (job_ptr->switch_st.state != SWITCH_STATE_COMPLETE_RETRY_WAIT))
		return SLURM_SUCCESS;

	job = _job_args_create(job_ptr);
	job->complete_cb = complete;
	if (job->job_info_buf)
		switch_p_jobinfo_pack(job_ptr->switch_jobinfo,
				      job->job_info_buf,
				      SLURM_PROTOCOL_VERSION);

	slurmscriptd_run_switch_lua(job->job_id, "slurm_switch_job_complete",
				    switch_get_timeout(), job->job_info_buf,
				    _complete_done, job);

	if (block_job_complete)
		*mode = SWITCH_COMPLETE_MODE_ASYNC_BLOCK_NODES;
	else
		*mode = SWITCH_COMPLETE_MODE_ASYNC;

	return SLURM_SUCCESS;
}

extern uint32_t switch_p_job_channel(job_record_t *job_ptr, char *node_name)
{
	return NO_VAL;
}

extern int switch_p_fs_init(stepd_step_rec_t *step)
{
	return SLURM_SUCCESS;
}

extern void switch_p_stepmgr_fini(uint32_t job_id) {}

extern void switch_p_stepmgr_init(void) {}
