Documentation for this module may be created at Module:Pg/doc

require 'Module:No globals'

local p = {}

-- Return a title using [[Special:MyLanguage]], which resolves to user language
-- at read time if that exists, or English otherwise
local function getMyLanguage(title)
	-- interwiki prefixes for wikis with translate extension
	-- created from https://phabricator.wikimedia.org/source/mediawiki-config/browse/master/wmf-config/InitialiseSettings.php$19151
	-- and https://commons.wikimedia.org/wiki/Special:Interwiki
	-- frwiktionary is excluded because there are multiple wiktionaries
	local multilang = {
		wmam = true,
		wmbe = true,
		betawikiversity = true,
		wmbr = true,
		wmbd = true,
		wmca = true,
		wmge = true,
		wmid = true,
		wmhi = true,
		incubator = true,
		m = true,
		meta = true,
		metawiki = true,
		metawikimedia = true,
		metawikipedia = true,
		wmno = true,
		otrswiki = true,
		vrtwiki = true,
		outreach = true,
		outreachwiki = true,
		wmpl = true,
		wmru = true,
		wmpunjabi = true,
		oldwikisource = true,
		species = true,
		wikispecies = true,
		wmse = true,
		testwiki = true,
		wmua = true,
		d = true,
		wikidata = true,
		wmania = true,
		wikimania = true,
	}
	if title.isExternal then
		if multilang[title.interwiki] then
			-- mw.title.interwiki only seperates the first interwiki or interlanguage
			-- prefix. that means this wouldn't work with a link that has both,
			-- eg 'wikt:fr:foo' -> 'wikt:Special:MyLanguage/fr:foo' which breaks.
			-- if the wiki supports translation, the link probably doesn't have an
			-- interlanguage prefix and Special:MyLanguage might be useful
			return mw.title.new(title.interwiki .. ':Special:MyLanguage/' .. title.nsText .. title.text)
		else
			-- wiki doesn't support translation, so don't try to add Special:MyLanguage
			return title
		end
	else
		return mw.title.new('Special:MyLanguage/' .. title.fullText)
	end
end

-- Get display title for pages translated using the Translate extension
local function getDisplayTitle(title, lang)
	local titlepage = mw.title.makeTitle('Translations', title.prefixedText .. '/Page display title/' .. lang)
	if titlepage.exists then
		local display = mw.getCurrentFrame():expandTemplate{ title = titlepage }
		if title.fragment ~= '' then
			display = display .. '#' .. title.fragment
		end
		return display
	else
		return nil
	end
end

function p.getLink(page, display, anchor, lang, useMyLanguage)
	-- Sort out things like nil, object etc. It is likely to be invalid title,
	-- but c’est la vie.
	local title = mw.title.new(tostring(page or ''))
	if not title then
		return '[['  .. page .. ']]'
	end
	if anchor then
		title.fragment = anchor
	end
	if title.isRedirect then
		local fragment = title.fragment
		title = title.redirectTarget
		if fragment ~= '' then
			title.fragment = fragment
		end
	end
	if useMyLanguage then
		if not display then
			display = getDisplayTitle(title, lang) or title.fullText
		end
		title = getMyLanguage(title)
	else
		if lang ~= 'en' then
			local subpage = title:subPageTitle(lang)
			if subpage.exists then
				-- version of target page exists in current page language, return that version
				subpage.fragment = title.fragment
				if not display then
					-- try to use translated page title
					display = getDisplayTitle(title, lang)
				end
				title = subpage
			else
				-- prepend Special:MyLanguage/ to return the target page in
				-- user’s preferred language if available
				if not display then
					display = title.fullText
				end
				title = getMyLanguage(title)
			end
		end
	end
	return '[['  .. title.fullText .. (display and '|' .. display or '') .. ']]'
end


function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {frameOnly = true})
	local lang = args.lang or mw.getCurrentFrame():preprocess('{{PAGELANGUAGE}}')
	return p.getLink(args.page, args.display, args.anchor, lang, false)
end

function p.pg2(frame)
	local args = require('Module:Arguments').getArgs(frame, {frameOnly = true})
	local lang = args.lang or mw.getCurrentFrame():preprocess('{{int:lang}}')
	return p.getLink(args[1], args[2], args.anchor, lang, true)
end

return p