local erosions = {}
local resistances = {}


--only available on init,
erosion.register_erosion = function(order)
	for i, nodename in ipairs(order)
	do
		nodename = minetest.registered_aliases[nodename] or nodename
		assert(type(nodename) == "string",
			"erosion orders must only contain strings")

		assert(not (erosions[nodename] and erosions[nodename] ~= nodename and i ~= #order),
			"Erosion trees can join but not branch. Relevant node: " .. nodename)
		if order[i + 1]
		then
			erosions[nodename] = order[i + 1]
		elseif not erosions[nodename]
		then
			erosions[nodename] = nodename
		end
	end
end
--while initiating display an error when anything is trying to erode
erosion.get_erosion_result = function()
	assert(false, "Cannot erode anything on init")
end


local function get_erosion_result(cid, power)

	while power > 0 and erosions[cid]
	do
		power = power - resistances[cid]
		if power > 0
		then
			cid = erosions[cid]
		end
	end
	return cid
end

do
	todo_on_done_postprocessing = {}
	erosion.do_once_postprocessing_done = function(func)
		assert(type(func) == "function", "complaint from erosion mod: " ..
			"tried to register value of type " .. type(func) ..
			" as do_once_postprocessing_is_done, must be function")
		table.insert(todo_on_done_postprocessing, func)
	end
	local function done_postprocessing()
		for i, f in ipairs(todo_on_done_postprocessing)
		do
			f() --respecc
		end
		todo_on_done_postprocessing = nil
		erosion.do_once_postprocessing_done = function(func)
			f()
		end
	end

	local relevant_groups =
	{
		crumbly = 0.5,
		cracky = 0.5,
		snappy = 0.1,
		explody = 0.1,
		choppy = 0.3,
	}

	--convert node names to content ids
	local function postprocess_erosions()
		local new_erosions = {}
		local function calculate_resistance_from_groups(groups)
			local resistance = 0
			for groupname, weight in pairs(relevant_groups)
			do
				local g = groups[groupname]
				if g
				then
					resistance = resistance + (4 - g) * weight
				end

			end
			return resistance
		end

		for this, next in pairs(erosions)
		do
			local ind = minetest.get_content_id(this)
			new_erosions[ind] = minetest.get_content_id(next)


			local def = minetest.registered_nodes[this]
			assert(def, "No registered node with name " .. this)

			local groups = def.groups or {}
			resistances[ind] =
				calculate_resistance_from_groups(groups)
			if resistances[ind] < 1 then resistances[ind] = 1 end
			resistances[this] = resistances[ind]
		end

		for k, v in pairs(new_erosions)
		do
			erosions[k] = v
		end
		new_erosions = nil

		--disable registering erosions late
		erosion.register_erosion =
			function()
				assert(false, "Cannot register erosions after init")
			end
		erosion.get_erosion_result  = get_erosion_result
		done_postprocessing()
	end

	--run this right after init, before any barrels can explode
	--but after aliases are all registered
	minetest.after(0.1, postprocess_erosions)
end
