-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore, pairs, string, table, tonumber,
      tostring
    = ipairs, minetest, nodecore, pairs, string, table, tonumber,
      tostring
local string_format, string_gmatch, string_match, string_sub,
      table_sort
    = string.format, string.gmatch, string.match, string.sub,
      table.sort
-- LUALOCALS > ---------------------------------------------------------

local modname = minetest.get_current_modname()

local known_settings = {}
local known_dirty

local prefix = "nc_"
local function setting_learn(key, title, comment, typename, typedata)
	if string_sub(key, 1, #prefix) ~= prefix then return end
	if known_settings[key] then return end
	known_settings[key] = {
		title = title,
		comment = comment,
		typename = typename,
		typedata = typedata
	}
	known_dirty = true
end

function nodecore.setting_string(key, default, title, comment)
	setting_learn(key, title, comment, "string",
		default and string_format("%q", default))
	local s = minetest.settings:get(key)
	return s == "" and default or s
end

function nodecore.setting_float(key, default, title, comment)
	setting_learn(key, title, comment, "float",
		default and tostring(default) or "")
	return tonumber(minetest.settings:get(key)) or default
end

function nodecore.setting_bool(key, default, title, comment)
	setting_learn(key, title, comment, "bool",
		default ~= nil and (default and "true" or "false") or "")
	return minetest.settings:get_bool(key, default)
end

------------------------------------------------------------------------

local function prefstr(str, pref)
	return str and (pref .. str) or ""
end
function nodecore.infodump(sub)
	local set = nodecore.setting_bool(
		minetest.get_current_modname() .. "_infodump" .. prefstr(sub, "_"),
		false,
		"Write info dump to world path - " .. (sub or "ALL"),
		[[Write out after startup (and possibly maintain while running)
		text files to the world path containing template metadata for
		development use.]]
	)
	if set or not sub then return set end
	return nodecore.infodump()
end

if nodecore.infodump("setting") then
	minetest.register_globalstep(function()
			if not known_dirty then return end
			known_dirty = nil

			local keys = {}
			for k in pairs(known_settings) do keys[#keys + 1] = k end
			table_sort(keys)

			local dump = "# ===== Automatically generated by " .. modname .. "\n"
			for _, k in ipairs(keys) do
				dump = dump .. "\n"
				local data = known_settings[k]
				if data.comment and string_match(data.comment, "%S") then
					local txt = ""
					for w in string_gmatch(data.comment, "(%S+)") do
						if #txt + #w + 1 > 71 then
							dump = dump .. "#" .. txt .. "\n"
							txt = ""
						end
						txt = txt .. " " .. w
					end
					if txt ~= "" then
						dump = dump .. "#" .. txt .. "\n"
					end
				end
				dump = dump .. string_format("%s (%s) %s %s\n", k,
					data.title or k, data.typename, data.typedata or "")
			end

			local p = minetest.get_worldpath() .. "/settingtypes.txt"
			minetest.safe_file_write(p, dump)
			return nodecore.log("info", "dumped settingtypes.txt")
		end)
end
