Documentation for this module may be created at မဝ်ဂျူ:string/replace last/doc

local str = {}

local function _getParameters(frame_args, arg_list)
	local new_args = {};
	local index = 1;
	local value;
	
	for _, arg in ipairs(arg_list) do
		value = frame_args[arg]
		if value == nil then
			value = frame_args[index];
			index = index + 1;
		end
		new_args[arg] = value;
	end
	
	return new_args;
end

function str.replace_last(source_str, pattern, replace, count, plain)
	if source_str == '' or pattern == '' or count <= 0 then
		return source_str;
	end
	
	if plain then
		pattern = require("Module:string utilities").pattern_escape(pattern);
		replace = require("Module:string utilities").replacement_escape(replace);
	end
	
	local result;
	local last_n_matches = {}
	local cycle = 1
	local matches_found = 0
	local i = nil
	
	while true do
		local mstart, mend = mw.ustring.find(source_str, pattern, i)
		if mstart == nil then break end
		last_n_matches[cycle] = { mstart, mend }
		cycle = cycle + 1
		if cycle > count then cycle = 1 end
		if matches_found < count then matches_found = matches_found + 1 end
		i = mend + 1
	end
	
	-- intentional; reverse sort
	table.sort(last_n_matches, function(a, b) return a[1] > b[1] end)
	
	local result = source_str
	
	for _, pair in ipairs(last_n_matches) do
		local mstart, mend = unpack(pair)
		result = mw.ustring.sub(result, 1, mstart - 1) .. mw.ustring.gsub(mw.ustring.sub(result, mstart, mend), pattern, replace) .. mw.ustring.sub(result, mend + 1)
	end
	
	return result;
end

function str.invoke(frame)
	local new_args = _getParameters(frame.args, { 'source', 'pattern', 'replace', 'count', 'plain' });
	local source_str = new_args['source'] or '';
	local pattern = new_args['pattern'] or '';
	local replace = new_args['replace'] or '';
	local count = tonumber(new_args['count']);
	local plain = new_args['plain'] or true;
	
	--plain = str._getBoolean(plain);
	plain = plain == "true"
	
	return str.replace_last(source_str, pattern, replace, count, plain)
end

return str