--[=[
	This module implements the {{multitrans}} template.

	Author: Benwing2, based on an idea from Rua.
	
	The idea is to reduce the memory usage of large translation tables by
	computing the whole table at once instead of through several separate calls.
	The entire text of the translation table should be passed as follows:
	
	{{multitrans|data=
* Abkhaz: {{tt|ab|аиқәаҵәа}}
* Acehnese: {{tt|ace|itam}}
* Afrikaans: {{tt+|af|swart}}
* Albanian: {{tt+|sq|zi}}
* Amharic: {{tt|am|ጥቁር}}
* Arabic: {{tt+|ar|أَسْوَد|m}}, {{tt|ar|سَوْدَاء|f}}, {{tt|ar|سُود|p}}
*: Moroccan Arabic: {{tt|ary|كحال|tr=kḥāl}}
* Armenian: {{tt|hy|սև}}
* Aromanian: {{tt|rup|negru}}, {{tt+|rup|laiu}}
* Asháninka: {{tt|cni|cheenkari}}, {{tt|cni|kisaari}}
* Assamese: {{tt|as|ক‌’লা}}, {{tt|as|কুলা}} {{qualifier|Central}}
* Asturian: {{tt|ast|ñegru}}, {{tt|ast|negru}}, {{tt|ast|prietu}}
* Atikamekw: {{tt|atj|makatewaw}}
* Avar: {{tt|av|чӏегӏера}}
* Aymara: {{tt|ay|ch’iyara}}
* Azerbaijani: {{tt+|az|qara}}
	[etc.]
	}}
	
	That is, take the original text and add a 't' to the beginning of translation
	templates:
		{{t|...}} -> {{tt|...}}
		{{t+|...}} -> {{tt+|...}}
		{{t-check|...}} -> {{tt-check|...}}
		{{t+check|...}} -> {{tt+check|...}}
		
	The {{tt*|...}} templates are pass-throughs, so that e.g.
	{{tt|ary|كحال|tr=kḥāl}} generates the literal text "⦃⦃t¦ary¦كحال¦tr=kḥāl⦄⦄",
	with braces replaced by brace-like Unicode chars and the pipe symbol
	replaced by a pipe-symbol-like Unicode char. These special chars are parsed
	by the Lua code and call the same code that underlyingly implements
	{{t}} and {{t+}}, but because this all happens inside a single module
	invocation instead of a lot of separate module invocations, it's much
	faster and more memory-efficient.
]=]

local export = {}
local m_languages = require("Module:languages")
local m_data
local m_indiv = {}
local m_links = require("Module:links")
-- not currently used
-- local m_parameters = require("Module:parameters")
local m_translations = require("Module:translations")

--[[
local params = {
	[1] = {required = true, default = "und"},
	[2] = {},
	[3] = {list = true},
	["alt"] = {},
	["id"] = {},
	["sc"] = {},
	["tr"] = {},
	["ts"] = {},
	["lit"] = {},
}
]]

local function process_translation(tname, combined_args, load, no_check_redundant_translit)
	local args = {}
	local i = 0
	
	for arg in mw.text.gsplit(combined_args, "¦", true) do
		-- I think the algorithm used by Mediawiki when parsing arguments is to
		-- strip whitespace in named arguments but not numbered arguments.
		-- The following commented-out code implements this for named arguments;
		-- but I don't think this is actually necessary because the pass-through
		-- template will already strip whitespace.
		-- local name, value = arg:match("^%s*(.-)%s*=%s*(.-)%s*$")
		local name, value = arg:match("^(.-)=(.-)$")
		if name then
			if value ~= "" then
				name = tonumber(name) or name
				args[name] = value
			end
		elseif arg and arg ~= "" then
			i = i + 1
			args[i] = arg
		end
	end

	local function get_orig_template()
		-- YUCK! If we return a normal template without a linked template name,
		-- it will get expanded. I tried surrounding with <nowiki>...</nowiki>
		-- but then those tags display; I tried using {{#tag:nowiki|...}} but
		-- you get the same thing; I tried &#123; but then that displays
		-- literally; etc.
		return '{{[[Template:t' .. tname .. '|t' .. tname .. ']]|' .. combined_args:gsub("¦", "|") .. '}}'
	end

	local function get_lang_obj(lang)
		local langdata
		if load == "all" then
			if not m_data then
				m_data = require("Module:languages/data/all")
			end
			langdata = m_data[lang]
		else
			local module_name = m_languages.getDataModuleName(lang)
			if module_name then
				if not m_indiv[module_name] then
					m_indiv[module_name] = mw.loadData("Module:" .. module_name)
				end
				langdata = m_indiv[module_name][lang]
			end
		end
		if not langdata then
			local obj = require("Module:etymology languages").getByCode(lang)
			if obj then
				return obj
			end
		end
		if not langdata then
			m_languages.err(lang, 1, nil, get_orig_template)
		end
		return m_languages.makeObject(lang, langdata)
	end

	local genders = {}
	for i=3, 20 do
		if args[i] then
			table.insert(genders, args[i])
		end
	end
	local lang_obj = get_lang_obj(args[1])
	-- FIXME, this is duplicated with [[Module:translations]]. We should see if
	-- we can consolidate.
	return m_translations.show_terminfo(
		{
			lang = lang_obj,
			sc = (args["sc"] and (require("Module:scripts").getByCode(args["sc"]) or error("The script code \"" .. args["sc"] .. "\" is not valid.")) or nil),
			track_sc = true,
			term = args[2] or (mw.title.getCurrentTitle().nsText == "Template" and "term") or nil,
			alt = args["alt"],
			id = args["id"],
			genders = genders,
			tr = args["tr"],
			ts = args["ts"],
			lit = args["lit"],
			interwiki = (tname == "t+" or tname == "t+check") and "tpos" or nil,
			no_check_redundant_translit = no_check_redundant_translit,
		},
		tname == "t-check" or tname == "t+check" or nil
	)
end

function export.show(frame)
	local wikicode = frame:getParent().args["data"]
	local load = frame:getParent().args["load"]
	local no_check_redundant_translit = frame:getParent().args["no-check-redundant-translit"]
	
	if not wikicode then
		return ""
	else
		local index = mw.ustring.find(wikicode, "⦃")
		if index == nil then
			error("Please replace Template:t by Template:tt, Template:t+ by Template:tt+")
		end

		if no_check_redundant_translit and (
			no_check_redundant_translit == "" or no_check_redundant_translit == "0" or
			no_check_redundant_translit == "no" or no_check_redundant_translit == "false"
		) then
			no_check_redundant_translit = false
		end
		local function if_error_then_log_backtrace(fn, msg)
			-- Can't tell xpcall to supply varargs to the function that is its
			-- first argument in Lua 5.1. Lua 5.2 would let us do
			-- xpcall(fn, error_handler, ...) which would internally
			-- call fn(...) in protected mode.
			return function(arg1, arg2)
				local ok, ret = xpcall(function() return fn(arg1, arg2) end, function(err)
					return msg .. ":\n" .. tostring(err) .. "\n" .. debug.traceback()
				end)
				if ok then
					return ret
				else
					mw.log(ret)
					error(msg .. "; see Lua logs")
				end
			end
		end
		local function do_process_translation(tname, combined_args)
			return process_translation(tname, combined_args, load, no_check_redundant_translit)
		end
		return (mw.ustring.gsub(
			wikicode,
			"⦃⦃(t[+%-]?c?h?e?c?k?)¦([^⦃⦄]+)⦄⦄",
			if_error_then_log_backtrace(do_process_translation, "Error in process_translation")
		))
	end
end

return export