require ('strict');
local get_args = require ('Module:Arguments').getArgs;
local data = mw.loadData ('Module:Current leader/data/sandbox');


--[[--------------------------< F O R M A T _ D A B _ N A M E >------------------------------------------------

leader name is expected to match our article title for that leader including parenthetical or natural disambiguation.
this function strips disambiguation and return the properly linked leader's name or, when |link=no, the unlinked
leader name.

]]

local function format_name (name, link)
	local display_name;
	for _, pattern in ipairs (data.dab_patterns_t) do
		if name:match (pattern) then											-- if leader name is disambiguated:
			display_name = name:gsub (pattern, '');								-- remove disambiguator to create <display_name> 
			break;																-- done so go make return value
		end
	end
	
	if link then																-- linked name is the default case
		if display_name then													-- did we strip disambiguation?
			return string.format ('[[%s|%s]]', name, display_name);				-- create a link to dab'd article
		else
			return string.format ('[[%s]]', name);								-- no disambiguation so make a simple link
		end
	else																		-- here when |link=no
		return display_name or name;											
	end
end


--[[--------------------------< U N I N V E R T >--------------------------------------------------------------

uninvert inverted country names from the template's {{{1}}} parameter.  There are a couple of common forms:
	'korea, republic of' → 'republic of korea'
	'comoros, union of the' → 'union of the comoros'; 'bahamas, the' → 'the bahamas'
where the inverted forms always contain a comma and always end in either 'of' or 'the'.  country names like
'taiwan, china' are not inverted so are not changed by this function.

the purpose of this function is to ease the maintanance burden imposed by the requirement to include inverted
names in Module:Current leader/data

]]

local function uninvert (country_name)
	for _, pattern in ipairs (data.uninvert_patterns) do						-- loop through the <uninvert_patterns> sequence
		local segment1, segment2 = country_name:match (pattern);				-- try to match <country_name> with <pattern>
		if segment1 then														-- set when there is a match; nil else
			return string.format ('%s %s', segment2, segment1);					-- uninvert and return
		end
	end
	
	return country_name;														-- does not need uninversion so return <country_name> as is
end


--[[--------------------------< M A I N >----------------------------------------------------------------------

implements {{Current leader}}.

{{#invoke:Current leader}}

]]

local function main (frame)
	local args_t = get_args (frame);											-- fetch template parameters
	local link = 'no' ~= args_t.link;											-- default is true, always link; |link=no then set <link> false
	local leader;																-- <leader> can be either a sequence of names or a simple string
	if args_t[1] and args_t[2] then												-- must have both {{{1}}} and {{{2}}} (country and office)
		local country = mw.ustring.lower(args_t[1]);
		country = uninvert (country);											-- uninvert inverted country names
		local office = mw.ustring.lower(args_t[2]);
		if data.synonyms_t[country] then
			leader = data.synonyms_t[country][office];
			if not leader then													-- here when {{{2}}} is not a recognized office; emit error message and abandon
				return string.format (data.error_messaging_t.fmt, data.error_messaging_t.office, office);
			end
		else																	-- here when {{{1}}} is not a recognized country synonym; emit error message and abandon
			return string.format (data.error_messaging_t.fmt, data.error_messaging_t.country, country);
		end
	else																		-- here when missing one or both of {{{1}}} and {{{2}}}; emit error message and abandon
		return string.format (data.error_messaging_t.fmt, data.error_messaging_t.missing, '');
	end

	local leader_t = 'string' == type (leader) and {leader} or leader;			-- convert simple string to sequence or point to the sequence

	local parsedLeader = {}														-- collect formatted leader names here
	
	for k, leader_name in ipairs (leader_t) do									-- for each name in the <leader_t> sequence
		parsedLeader[k] = format_name (leader_name, link);						-- format and add to the collection
	end
	return frame:expandTemplate{ title = 'enum', args = parsedLeader };			-- make a prose-style list and done
end


--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]

return {
	main = main
	}